functions and variable?

Whatever is on your mind, whether Lisp related or not.
Post Reply
Jonsul
Posts: 18
Joined: Mon Apr 19, 2010 7:56 am

functions and variable?

Post by Jonsul » Sat May 15, 2010 6:52 pm

Just an idea or something that has been itching me for a while. I'm just getting into real programing, before I touched at some stuff like javascript but never anything big. And now that I've been learning lisp and python and playing around with them I had an "Ah..." moment. There's not much a difference between variables and functions, especially in lisp where everything is self evaluating. Both things hold data, functions just hold a problem to be solved. So I was wondering, now I haven't searched on this a lot, but why hasn't anybody just blended variables and functions together? Say:

Code: Select all

x=56
y="string"
z= (format t "~a ~a" x y)
And just typing z returns (format t "~a ~a" x y) which executes to: '56 string'
I could just be missing something I guess, and I'm not proposing another language. Just random daydreaming while bored.

nuntius
Posts: 538
Joined: Sat Aug 09, 2008 10:44 am
Location: Newton, MA

Re: functions and variable?

Post by nuntius » Sat May 15, 2010 8:22 pm

Look at Scheme. In Common Lisp, the first item in a code list is treated as a function/macro and the rest are treated as arguments. A symbol is a data structure, and CL retrieves the symbol-function or symbol-value depending on whether it appears in a function or argument position.

In Scheme, there is no such distinction. The "symbol-value" is always used; it may contain a function or any other value.

This is one of the major differences between CL and Scheme. This paper introduced the lisp1/lisp2 notation to describe it.

Which is better? Is peanut butter better than jelly?

Jasper
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands
Contact:

Re: functions and variable?

Post by Jasper » Tue May 18, 2010 7:55 am

In Scheme, the namespace of the variables holding functions are the same as that of the regular variables, in CL it isn't. But (define zero-arguments () stuff) zero-arguments won't presumably won't evaluate, just returns the function, as it should, because that is what it is. I think that is what he means, that the variable changes allong with other variables.

He means to ask if you can make variables depend on other variables The following will do so locally:

Code: Select all

(defmacro let-follow (vars &body body)
  "Variables that act like functions."
  (let*((functions ;;Paired functions. (looking into them to see which gensym.)
         (mapcar (lambda (var &key (gs (gensym)))
                   `((,gs () ;;Function to get variable.
                       (or ,gs ,(cadr var)))
                       ((setf ,gs) (to) ;;Function to set variable.
                      (setf ,gs to))))
                 vars))
        (genvars (mapcar #'caar functions)))
    `(let*(,@genvars);Make the symbols refer to the functions.
       (declare (ignorable ,@genvars))		 
       (symbol-macrolet (,@(mapcar (lambda (var fun) 
                                     `(,(car var) (,(caar fun))))
                                    vars functions))
       ;Flatten out functions into labels. (unlike flet these are allowed to depend on eachother.)
         (labels (,@(mapcan #'identity functions)) 
            (declare (ignorable ,@(mapcan (lambda (var)
                                           `((function ,var)
                                             (function (setf ,var))))
                                         genvars)))
           ,@body)))))

(let-follow ((x 0) (y 5) (z (+ x y)))
  (print z) ;;Weirdly enough setq works, guessing symbolmacros change to counter potential confusion.
  (print (setq x 3)) 
  (print z)))
Which just makes (setf-able)local functions, and then uses a local symbol-macrolet to turn the symbols into that function. Setting them overrides the function forever-after, and it isn't particularly efficient, but there you go.

To be honest, it doesn't seem particularly useful to me. It is much better to learn how to use FLET and LABELS themselves. It promotes destructive programming too much, and if it is a function, why not call it as such? (Auto-memoization is sortah another topic, btw.) This might be handier for special variables, but there too, you can probably get what you want in functions.

Edit: we might both be misinterpreting you though.. why the '=' mixed with the CL code, do you mean that you want a syntax more like other languages mixed with lisp? I do think that might be a good idea, for instance ML/Haskell-like.. i'd make it but i can't find how to conveniently get the argument list.

Jonsul
Posts: 18
Joined: Mon Apr 19, 2010 7:56 am

Re: functions and variable?

Post by Jonsul » Tue May 18, 2010 9:15 pm

Ahhh... honestly I'm not sure :shock:

I'm young, just getting started in programing so I only really understood 3/4 of what you wrote haha. What I was basically doing was just really putting how my mind thinks of programing on paper. Telling that while teaching myself I realized that I now saw variables, functions, and objects as the same thing. All they are to me are storage areas that hold different information or organize it different then the other. Then I was asking why hasn't anybody just made them the same thing? So I illustrated in a fictional language.
Like in the fictional language, since all of them are the same then there would be no need for keywords like define, defun, or def
To declare a variable:

Code: Select all

x="test string"
To declare a function:

Code: Select all

y(what)= (format t "This is a ~a" what)
Lastly I see objects as just a way to organize code. I haven't really thought of objects a whole lot but I guess they are just a variable or function namespace tagged onto another's. And in this way you could simply make a new object by doing something like this:

Code: Select all

obj = object
And add on init variable like this:

Code: Select all

obj(name) = object
        obj.name=name
        obj.age=46
        obj.alive= t
And then to organize your code just tag on namespaces:

Code: Select all

obj.explode = (format t "Boom!")
        obj.alive= nil
I guess how it works is that it sees the call to a namespace and checks for it like normal, but if it doesn't exist it just creates it with what's supplied. When that came to me I thought errors could occur where you accidentally mistype a variable and it creates one, but I guess that wouldn't be a problem if it required a '=' after it. I don't know if there's anything to it, but I really like how it makes programing look a lot more like algebra :D

Jasper
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands
Contact:

Re: functions and variable?

Post by Jasper » Wed May 19, 2010 2:32 am

I made something like that way before.. Here it is. Although i would do that wholly differently now, treating the :=/= operator specially can save a bunch of parenthesis and (corresponding)nestedness, so i think lispers should make some kind of standard way of doing it. Note that the nestedness can also be helped a bit by denesting. (Though i have overstated its usefullness before, it can only channel usefulness of macros used with it.)

Perhaps something like this

Code: Select all

(defmacro =body (&body body)
  "Allow := to define variables/functions at the start of bodies."
  (let ((i (position := body)))
    (typecase i
      ((eql 1)
       `(let ((,(car body) ,(caddr body))) (=body ,@(cdddr body))))
      ((eql 2)
       (destructuring-bind (name args = fun &body body) body
	 (assert (eql = :=))
         `(flet ((,name ,args ,fun))
            (=body ,@body))))
      (null
       `(progn ,@body)))))

(=body a := 1 b := 4
       a+b (x) := (* x a b)
       (+ a b (a+b 3)))

(defmacro def (name args = &body body)
  (assert (eql = :=))
  `(defun ,name ,args (=body ,@body)))

(macroexpand-1 '(def sqr (x) := (* x x)))
I used := because that still allows = to be special as binary op. It can be improved, but this is still very limited., you have to use =body again to start it inside a COND, WITH-SLOTS etcetera, and each body must start with continuous defining vars/funs, you can't have an expression and then continue defining vars/funs. The problem in improving this is that you have to work through other macros to make := work on them a &body-hook would be handy. But i guess lispers often use a subset of types of macros, so it should be completely possible to make something useful without going into other peoples' macros.(I could endow =body with denest-like properties.)

Not happy with the thing.slot notation, it is arbitrary. And i am also not entirely sure what you mean by that. To me, it seems like you're conflating =-as-in definition, and =-as-in setting a little there. It also seems like you don't want to repeat 'obj' in obj.thing for each thing.

Jonsul
Posts: 18
Joined: Mon Apr 19, 2010 7:56 am

Re: functions and variable?

Post by Jonsul » Wed May 19, 2010 11:57 pm

Lol yeah I come from a javascript background, so I'm not used to things like classes. Maybe by just writing .slot within the codeblock attaches it. I think that could easily be done. Can you elaborate "=-as-in definition, and =-as-in setting", if I understand what you mean I think I've done that on purpose

Basically I'm just making all the parts of programing the same thing with subtle differences. I think that makes things much more simpler. I was surprised that lua and scheme already do a lot of this. I was looking around and found that a function in scheme is basically a variable that holds a lambda function. But I find it weird that it's kinda obscured that it works like that. At least to me ^-^

I think a system like this could bring extreme flexibility to programing. Would be an interesting experimental language

nuntius
Posts: 538
Joined: Sat Aug 09, 2008 10:44 am
Location: Newton, MA

Re: functions and variable?

Post by nuntius » Thu May 20, 2010 9:18 am

Re: "= as definition" vs "= as setting"

In some languages, using a token of a certain form causes a variable with that name to be created. In others, you have to explicitly declare your variables.
When writing large codebases, stupid typos can cause obscure bugs. Thus I prefer the latter style.


Re: functions in variables

CL already allows this; the only caveat is you have to "funcall" the variable in order to execute its contents as a function. Again, there are arguments for both forms; I like shadowing verbs like "list" with nouns -- something unadvised and requiring hygiene in scheme. I've also heard claims that the two-namespace arrangement allows for more optimal code; you can move checks that the value is actually a function from the place of evaluation to the place of assignment.

Jonsul
Posts: 18
Joined: Mon Apr 19, 2010 7:56 am

Re: functions and variable?

Post by Jonsul » Thu May 20, 2010 11:56 pm

I think I understand. Maybe a better way to code it would be like this then.

Code: Select all

thing(name) = 
        .name=name
        .age=46
        .alive= t
Sorry I just got done with some python programing and carried over the "class thing(object):". This way I guess I could write a macro to add code from the object quoted if you wanted to work from a past object created. Like.

Code: Select all

thing(name) =  
        add other-object
        .name=name
        .age=46
        .alive= t
With anything you create being all at once a variable, function, and object all in one it's pretty interesting. Once I have more time on my hands I'd love to experiment on this. I'm still in the learning process big time and am largely self taught. lol so if anything I discuss is kinda confusing I guess it's because I've only gone to one small c++ class in highschool. So any methods or program planing I have I created myself^^
Working on an encryption program right now.

Post Reply