Variable reference in structures

Discussion of Common Lisp
Goheeca
Posts: 271
Joined: Thu May 10, 2012 12:54 pm
Contact:

Re: Variable reference in structures

Post by Goheeca » Wed Aug 19, 2015 5:37 am

Well, look at this wiki page to differentiate the Java methods and CLOS methods. And look at this manifestation of CLOS flexibility.
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.

J.Owlsteam
Posts: 21
Joined: Wed Jul 29, 2015 7:25 am

Re: Variable reference in structures

Post by J.Owlsteam » Thu Aug 20, 2015 6:02 pm

Good evening Goheeca and thank for the links. It's quite a coincidence that I came to read your post now, as it's just ten minutes that I've finished to read Sonja about multimethods :D Well, I have to admit to be a little doubtful about them... on the one hand, I like to have the possibility to do the same thing in different ways and so, I'm glad to add this new tool to my collection, however on the other... actually I also think I'll try my best to avoid to use it :D
Maybe it's just due to my habit to java or to my sloppy experience, so please correct me if I'm in error, but I feel much more comfortable with the (I guess) traditional approach: if I have to model the relationship between two objects of different classes, I like to think that there fits the introduction of a third class, whose slots I can fill with the objects. Then, I can define a single method in wich I can call the other objects's methods, comparing them, etc. Finally I will have a single structurated stream and an additional level of abstraction representing the relationship I was modeling.

What do you think about it? Is it just a matter of sake or are there circumstances under wich one approach is preferrable to the other?

Goheeca
Posts: 271
Joined: Thu May 10, 2012 12:54 pm
Contact:

Re: Variable reference in structures

Post by Goheeca » Fri Aug 21, 2015 3:49 am

Well, don't avoid anything, you'll just use it anyway in a limited way (as "singlemethods") most of the time so let yourself make a decision later on (per project/module). The thing is that Java implements OOP in its own way and from it follows that there are Java specific design patterns, CLOS is different so as the usage.

I don't mean you should abandon what you're familiar with, but rather to acquaint with a different implementation of OOP thoroughly.
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.

J.Owlsteam
Posts: 21
Joined: Wed Jul 29, 2015 7:25 am

Re: Variable reference in structures

Post by J.Owlsteam » Fri Aug 21, 2015 10:27 am

Sure sure you're right, at this purpose I'm seeking for different opinions. On a first look, it seems that as the number of specializers will increment, I'll also have an exponential growth of the methods to define but, probably, it is possibile to more efficently combine the two approaches and avoid it. Well, in any case to not fossilize on Java patterns is a good advice, I'll contine my way trough the book ;)

Goheeca
Posts: 271
Joined: Thu May 10, 2012 12:54 pm
Contact:

Re: Variable reference in structures

Post by Goheeca » Fri Aug 21, 2015 11:37 am

There are other possibilities, you can write a macro which would cover the combinations or create your own subclass of generic-function* which would deal with the arguments by sorting of those or whatever. I'd like just to point out another angle of view.

* With the help of MOP and closer-mop is the library unificating that API among the CL implementations.
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.

edgar-rft
Posts: 226
Joined: Fri Aug 06, 2010 6:34 am
Location: Germany

Re: Variable reference in structures

Post by edgar-rft » Fri Aug 21, 2015 2:06 pm

In Common Lisp, using multimethods is only one option of many. You do not need to use them if you don't want, but they can help in some situations. In contrast to most other programming languages, in Common Lisp there is no paradigm like "you must solve things in one specific way because there is no other", instead there are often many different ways how the same problem can be solved, what makes learning Lisp a bit complicated.
J.Owlsteam wrote:It seems that as the number of specializers will increment, I'll also have an exponential growth of the methods to define.
That's correct and also the more specialized arguments per method, the slower the entire dispatch machinery will become. Both are things to consider when you need to decide what's the best way to solve a problem. But usually, what's the "best way" depends on the problem, not so much on the programming language, where languages that offer more ways to do things have better chances to solve a broader range of problems.

It takes some time (usually several years) and lots of exploration and experimentation until you find your way how *you* would like to work with Lisp. This is the reason for the partially justified myth that "the Common Lisp community never ever can agree on anything at all", just simply because many people have "their own way" how they use Lisp. The more ways exist how a problem could be solved, the more disagreemant about the "best way" will be the inevitable consequence.

I'm not such a nerd who thinks that Common Lisp is the one and only programming language and all other languages are sh*t. But unfortunately my Java knowledge is rather poor, Goheeca seems to know Java better than me.

- edgar
Last edited by edgar-rft on Fri Aug 21, 2015 7:16 pm, edited 1 time in total.

Goheeca
Posts: 271
Joined: Thu May 10, 2012 12:54 pm
Contact:

Re: Variable reference in structures

Post by Goheeca » Fri Aug 21, 2015 2:40 pm

I'd say Java made a big step with Java 8 and loosened the paradigm.
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.

J.Owlsteam
Posts: 21
Joined: Wed Jul 29, 2015 7:25 am

Re: Variable reference in structures

Post by J.Owlsteam » Sun Aug 23, 2015 6:02 am

Well I have to admit I yet have a little experience in Java too... but while it could seem to be a contradiction, at the moment I'm loving both the languages for quite opposite reasons, one for the rigid structure and the other for the freedom of actually "do what you think", or almost... maybe, my concern begins when this freedom becomes "too much", and some apects are left to be defined by the implementation, while I wuold ever like to have a standard reference... well, but maybe this will be the matter for an other topic :)

marcoxa
Posts: 85
Joined: Thu Aug 14, 2008 6:31 pm

Re: Variable reference in structures

Post by marcoxa » Mon Nov 30, 2015 5:50 am

edgar-rft wrote:
J.Owlsteam wrote: ...

It's possible to overwrite the constructor for a self-defined structure to implement LET* behaviour:

Code: Select all

(defstruct foo a b c)

;; IMPORTANT: save the original MAKE-FOO constructor FIRST!
(defparameter *make-foo* (symbol-function 'make-foo))

(defmacro make-foo (&key a b c)
  ;; create local variables for the EVALUATED arguments
  ;; that SHADOW the parameter variables with the same name
  `(let* ((a ,a)
          (b ,b)
          (c ,c))
     ;; call the original constructor
     (funcall *make-foo* :a a :b b :c c)))
Now you can write things like:

Code: Select all

(make-foo :a 1 :b 2 :c (+ a b)) => #S(FOO :A 1 :B 2 :C 3)
But you still run into problems if you reference variables that have not specified before. For example, this still won't work:

Code: Select all

(make-foo :a 1 :b (+ a c) :c 2) => error: unbound variable C
The reason is just simply:

Code: Select all

(defmacro make-foo (&key a b c)
  (let* ((a ,a)    ; 1
         (b ,b)    ; (+ a c) <- A is known, C is still unknown
         (c ,c))
    (funcall *make-foo* :a a :b b :c c)))
For finding a LET* binding order that doesn't produce these problems you need to investigate the values of all arguments before the LET* binding. This is possible, too, but it will take an amount of code that really makes no sense anymore.

I only wanted to demonstrate that it's more difficult to create an object system than just rewriting a simple constructor... :shock:

- edgar
Actually, without going the CLOS route, DEFSTRUCT gives you plenty of leeway to achieve what the OP asked for, without "saving" the constructor.

Code: Select all

CL-USER 1 > (defstruct (foo (:constructor make-foo (a b &aux (c (+ a b)))))
   a
   b
   c)
FOO

CL-USER 2 > (make-foo 2 3)
#S(FOO :A 2 :B 3 :C 5)
The :constructor option to DEFSTRUCT is quite flexible. Not only it allows you to bypass the standard constructor generation, it allows you to have different (more than one) constructors for your struct. I blogged about it some time ago http://within-parens.blogspot.it/2011/0 ... ricks.html.

Cheers

Marco
Marco Antoniotti

Post Reply