Earlier quoted context omitted.
I agree that Lisp is not always terse, which surprised me at first too. You can abstract many constructs and eradicate redundancy, but at some point, your only chance of being terser is to use reader macros. However, doing so might not be a good idea either. There are libraries out there that provide syntactic sugar for Common Lisp, which is often discarded because (i) they define their own "ghetto" dialect of Lisp (…
Yeah, that's how I do it sometimes with other peoples code. But with my own code I much prefer using structs. Makes it much clearer to read and there is little implicit structure like with an ordered list. So my preferred way would look more like: (let ((struct (my-get-decoded-time))) (format t "Year: ~A~%Seconds: ~A" (time-year struct) (time-seconds struct))) With the original multiple value return, if there were a…
Returning multiple values from functions in C++
51–60 of 67 posts
Re: Returning multiple values from functions in C++
#52Earlier quoted context omitted.
Maybe this is different in CL, but in scheme, if you're using a procedure that returns multiple values, there is no default return, or wrapping the multiple values into a list: You have to use call-with-values, any number of srfis providing sugar, most commonly srfi-8, although 11 and 71 also exist, and without the sugar, god knows how many lambdas. EVERY. SINGLE. TIME. You want to call a function that returns multip…
You might want to learn Common Lisp BEFORE you make statements about how a feature of the language is obsolete or not.
And even the new explanation, I STILL don't like MVR. I think that returning a list or other data structure, or just writing two functions, is much clearer, and lends itself better to function chaining. Sure, in CL there's a default, which makes things a little better, but what if you want the other one? I don't want to write
(multiple-value-bind (a b) (foo bar baz) b)
all over my codebase, and the scheme equivalent is just as bad, if not worse.Re: Returning multiple values from functions in C++
#53Earlier quoted context omitted.
Sometimes Lisp can get annoying though. I've used libraries where a function might return 5-6 values and I only need the first and last. I need to bind all of them and then (declare (ignore...)) the useless bits otherwise I get compiler warnings. It's an annoyance, because I always feel the general ethos of Lisp is to eliminate tedious typing and multiple value returns frequently add a lot of cruft.
Common Lisp is a programmable programming language. You need to hack around it. Don't like it? Improve it. Sketch: (defun make-vars (vars &aux syms) "creates uninterned symbols for vars named NIL. Returns a list with those replaced and a list of the new syms." (values (loop for var in vars if (eq var NIL) collect (let ((sym (gensym "ignore"))) (push sym syms) sym) else collect var) syms)) (defmacro multiple-value-bin…
Re: Returning multiple values from functions in C++
#54Earlier quoted context omitted.
Common Lisp is a programmable programming language. You need to hack around it. Don't like it? Improve it. Sketch: (defun make-vars (vars &aux syms) "creates uninterned symbols for vars named NIL. Returns a list with those replaced and a list of the new syms." (values (loop for var in vars if (eq var NIL) collect (let ((sym (gensym "ignore"))) (push sym syms) sym) else collect var) syms)) (defmacro multiple-value-bin…
I have a hunch that you defined make-vars as a separate function just to be able to nest two multiple-value-bind, one in the macro and one in the expanded form ;-)
Re: Returning multiple values from functions in C++
#55Earlier quoted context omitted.
You might want to learn Common Lisp BEFORE you make statements about how a feature of the language is obsolete or not.
I was talking about the general idea of MVR, AND how I thought is was implemented in lisp. I was wrong. This happens sometimes. And even the new explanation, I STILL don't like MVR. I think that returning a list or other data structure, or just writing two functions, is much clearer, and lends itself better to function chaining. Sure, in CL there's a default, which makes things a little better, but what if you want t…
Generally speaking, taking a secondary value alone feels like a bad use of MVR (it happens rarely with standard functions and most libraries).
MVR are not intended to be substitute to other data-structures. As said elsewhere, you can and should use structs, classes, lists, hash-tables,...
After all, why do we use multiple values instead of a single struct for functions arguments? Because in CL and other languages, unlike in Haskell, you don't want to define an ADT for all your functions or rely on currying. But if you start putting too many coupled parameters in your functions, it starts to smell fishy.
Extracting a single value is easy, by the way:
(nth-value 1 (foo bar baz))Re: Returning multiple values from functions in C++
#56Earlier quoted context omitted.
Sometimes Lisp can get annoying though. I've used libraries where a function might return 5-6 values and I only need the first and last. I need to bind all of them and then (declare (ignore...)) the useless bits otherwise I get compiler warnings. It's an annoyance, because I always feel the general ethos of Lisp is to eliminate tedious typing and multiple value returns frequently add a lot of cruft.
Common Lisp is a programmable programming language. You need to hack around it. Don't like it? Improve it. Sketch: (defun make-vars (vars &aux syms) "creates uninterned symbols for vars named NIL. Returns a list with those replaced and a list of the new syms." (values (loop for var in vars if (eq var NIL) collect (let ((sym (gensym "ignore"))) (push sym syms) sym) else collect var) syms)) (defmacro multiple-value-bin…
Of course it now also leads to one of Lisp's other problems; namely that after a while everyone ends up programming in their own private language of accumulated hacks :D
Re: Returning multiple values from functions in C++
#57Earlier quoted context omitted.
You might want to learn Common Lisp BEFORE you make statements about how a feature of the language is obsolete or not.
I was talking about the general idea of MVR, AND how I thought is was implemented in lisp. I was wrong. This happens sometimes. And even the new explanation, I STILL don't like MVR. I think that returning a list or other data structure, or just writing two functions, is much clearer, and lends itself better to function chaining. Sure, in CL there's a default, which makes things a little better, but what if you want t…
CL-USER 76 > (nth-value 1 (values 'a 'b 'c 'd))
B
While you are at it, check out the feature of 'Macros' in Lisp, which allows everyone to write code to shorten this stuff. See my code in this thread for a macro which then allows you to write: (multiple-value-bind-some (NIL b)
(foo bar baz)
b)
One then can name ignored variables as NIL in the source code...Re: Returning multiple values from functions in C++
#58For a moment, I thought they had added true multiple value return to C++. I am sooo glad they didn't. The lisp folks added it way back, and it has been an ugly scar on the language ever since. Why do real multi-value returns suck? because they don't compose well, they're awkward as all heck to use, and require wrapping certain function calls in really weird constructs. The PROPER way to do multiple values is to retur…
Re: Returning multiple values from functions in C++
#59Earlier quoted context omitted.
Common Lisp is a programmable programming language. You need to hack around it. Don't like it? Improve it. Sketch: (defun make-vars (vars &aux syms) "creates uninterned symbols for vars named NIL. Returns a list with those replaced and a list of the new syms." (values (loop for var in vars if (eq var NIL) collect (let ((sym (gensym "ignore"))) (push sym syms) sym) else collect var) syms)) (defmacro multiple-value-bin…
Yeah, that's a great example of the power of Lisp! Of course it now also leads to one of Lisp's other problems; namely that after a while everyone ends up programming in their own private language of accumulated hacks :D
1) Learn to deal with a language which has an infinite number of syntactic abstractions.
2) Learn the typical patterns of syntactic abstractions (WITH- , BIND-, DEF- ...).
3) Learn how to write your own abstractions.
Then groups will settle on common (!) Lisp patterns. See for example:
https://common-lisp.net/project/alexandria/
There are lots of libraries which provide language extensions, which are used by many people.
The extremes in Lisp are then:
* no syntactic abstractions -> the power of Lisp wasted
* using those syntactic abstractions which are approved by user groups, due to inclusion into libraries
Above choices are relatively conservative.
As another extreme, it is fully possible to change the language - but then Common Lisp provides more than macros to do so. See for example reader macros, CLOS MOP, customs evaluators/compilers, code walkers, ...
Re: Returning multiple values from functions in C++
#60Earlier quoted context omitted.
Yeah, that's a great example of the power of Lisp! Of course it now also leads to one of Lisp's other problems; namely that after a while everyone ends up programming in their own private language of accumulated hacks :D
The user needs to learn more than in Java: 1) Learn to deal with a language which has an infinite number of syntactic abstractions. 2) Learn the typical patterns of syntactic abstractions (WITH- , BIND-, DEF- ...). 3) Learn how to write your own abstractions. Then groups will settle on common (!) Lisp patterns. See for example: https://common-lisp.net/project/alexandria/ There are lots of libraries which provide lang…
Now I'm trying to make a concerted effort to follow the recommendations here:
http://eudoxia.me/article/common-lisp-sotu-2015/
Hopefully this will lead to a modern set of consolidated libraries. Effectively a new Common Lisp standard: CL-20xx