Do schemers really?
never liked the c[ad][ad]+r thing
lispish languages allow you to define your own cars and cdrs theres no need for the bigger symbols to be set in standard
Why not? Which one do you prefer `(cdr (cdr x))` or `(cddr x)`
cdr is an anti-pattern, you should be using list destructuring and pattern matching
I particularly like the scheme I created for doubly-linked lists: CAR and CDR behave as expected, but there's also CBR, which is the backwards link; this pleasantly uses A, B, C, and D. The code I wrote to generate all CNNR, CNNNR, and CNNNNR functions at READ time wasn't pretty, however.
I think it makes a clearer intention to use first_, second, rest etc on flat lists with a known and finite structure, and car, cdr, cadr etc on recursive functions and on other structures made of conses like trees, usually referred to as ``improper lists''.
Cniles often say that being terse is good but I don't know... with a proper editor (GNU Emacs + company-mode or similar), you should have some kind of autocomplete feature. Simple abbreviation like CAAR or CADR are easy to understand but it can get out of hand very easily.
>>6
this is also what scheme vectors are but the standard pushes implementations to optimize vectors here
sure they can skit but its less likely to optimize `(caddr x)`
>7
dimwit cnile says terse is good because their execution environment cant handle more
midwit lipth commoner says terse is bad because modern machines can already handle the sideeffects of worse is better
ivywit schemer says terse is good because it keeps design proper and allows ease of generating strict proofs while they still use a lisp machine like environment to program in their own scheme >>5
and you decided to use a lisp machine like environment thats the worst lisp as an example of a proper editor
>>7,8
I'd agree that making third generic for both vectors and lists is a good idea, while making caddr the same would be stupid.
Terseness is only good up to the point where it remains obvious what something is, and I think lispers/schemers understand this well. I don't think C programmers have a right to engage in a terseness debate when any given C program of around 200 lines could be written in less than 20 lines of Lisp or Scheme with actual semantics. We can hang our hats once an APL programmer shows up.
>>9
can you tersely define for a standard how this third generic gets optimized at a lower and more abstract level where having vectors and improper lists defined is moot
otherwise it doesnt belong in the standard and its something you can already do with scheme
i agree the standard has too many vector bits scheme isnt a shining example of terseness but it departs greatly from the common lipth goop slide into a sink
im waiting for another apl programmer to make an argument but since you understand proper etiquette here
scheme allows some or all if you wish imo macros just fit the case forms of apls shortening while most lipth implementations omit even supporting λ by default
sure you can argue about unicode but some modern apl doesnt
and i will say both of these arent real arguments you can even use a emacs mode for translating long goop into terse symbols locally
Terseness is only good up to the point where it remains obvious what something is
isnt the extreme what cniles broken vocabulary believes terseness is
incomphrenciable goop isnt terseness the word implies theres still a concisely defined subject
Of speech or style: brief, concise, to the point.
Synonyms: concise, succinct
even better it comes from a latin word tersus
clean, neat, rubbed or wiped (off), cleansed, having been cleansed
pure, correct, nice, terse, spruce, neat
is errccwrkprtpwo() any of those you already know the answer
now i will say r7rs-tiny has-a-few-goop-procedures but some of them are justified
call/cc this is cnile i need to know cc means current continuation and / with by looking at it first glance not because i have background information from studying call/cc
instead the emacs mode is justified here as the local programmer i know what symbols i consider equivalent to call-with-current-continuation
sure another solution is a proper (help) but this is something that should already be there especially for standard procedures and now when someone else goes to read it they have to manually look up call/cc
it can be acceptable when the concept needs paragraphs to describe to someone with baseline knowledge in that case call/cc should scream / is with and cc is current continuation but there is no consistent nomenclature where / acts as a combination in r7rs-tiny unlike -> which is even strictly defined to return another type of object
the nice thing about apl is once you understand the graphemes enough and the bases they form things like quadwords its universality accepted how those symbols get used so you arent writing split-at-obtuse-point-five because there is no need and it removes the broken need for verbosity in procedure names
i recommend a glossary using logical graphemes that works with proper lisp environments over split-at-vector-point-five that way someone reading can just hover or something else configured and see the verbose procedure name until they inherit the personal nomenclature the author has for symbols
My issue is that it is backwards, I know that's how it is when you write things out, but I like piping better.
elaborate upon this http://snow-fort.org/s/fisher.cx/robert/fisherro/pipe/1.0.0/index.html for your preferences relevance
My other car is a cdr 〜( ̄▽ ̄〜)
Problem?
CUDDER! (ノ>ω<)ノ :。・:*:・゚’★,。・:*:・゚’☆
>>15
now that's a name i ain't seen for a long time *crack*
You might be cute, but I'm cudder.
midwit discussion where situational is treated as universal
common lisp has like dozen different ways to destructure a list from which you can choose based on what you're doing. often those ways trade greater upfront work, for lesser domain work. but sometimes you start with more domain work, and then having identified an abstraction you factor it out.
cons exist at the lowest level of abstraction, it's a fundamental mechanism for dealing with the fact that von neumann machine doesn't let you resize things without relocating. you can build more complicated structures out of cons, like lists, but also variations on structs, or more elaborate algorithm specific data structures.
the lowest level way of manipulating a cons-cells-based-thing is using a combination of cars and cdrs, where c[ad]r is a clever hack that lets you reach down the cons indirection tree in a single call. after a while one might lose track of all the necessary c[ad]r combinations, so in the olden days you'd wrap an elaborate c[ad]r in its own semantic function. these days you have more mechanisms, like wrapping your lists in defstrcturs, or replacing lists with structs altogether, or whatever.
there is, to conclude, no one way. you can write an elaborate chunky code that's got caddrs and cddars all over hte place, and refactoring it to some sanity later. or maybe you never refactor it because it's good enough. but it's handy that mechanism is there.
common lisp has like dozen different ways to destructure a list
i'm not as familiar with cl as i'd like, what ways are there besides destructuring-bind and loop?
>>19
c[ad]r
first, second, nth
(defstruct (foo (:type list)) a b c) (foo-b '(1 2 3)) ;=> 2
destructuring-bind
variations on (loop for (x y) on '(1 2 3 4) by #'cddr)
(defun foo (a b c) b) (apply #'foo '(1 2 3))
(progv '(a b c) '(1 2 3) b)
assoc/getf, (defun foo (&key a b c) c) (apply #'foo '(:a 2 :c 3))
that's off the top of my head, as far how i've approached list structures. but i maybe missed one or two more at most, so i was wrong it's less than a dozen.
>>20
thanks, i hadn't seen progv before. using functions is interesting as i suspect all list destructuring mechanisms could be decomposed into lambdas, for instance a pattern [(a (b c) d ...) (list a c)]
could be compiled to
(apply
(lambda (a bc . d)
(apply
(lambda (b c) (list a c)) bc))
'(1 (2 3) 4))
returning (1 3)
>>21
LET wasn't immediately invented, and if you read sufficiently old lisp code
(let ((b 2) (c 3))
(sqrt (+ (expt b 2) (expt c 2))))
would be written as
((LAMBDA (B C)
(SQRT (+ (EXPT B 2) (EXPT C 2))))
2 3)
they called it "lambda-binding"
lisp news for may 25, 1978 says that several standard macros have been added, LET is one of them. and explicitly defines LET as
(LET ((V1 E1) (V2 E2) . . . (VN EN)) F1 F2 . . . FK)
==>
((LAMBDA (V1 V2 . . . VN)
F1 F2 . . . FK)
E1 E2 . . . EN)
and then sept 17, 1978,
[1] New autoloadable interpreter macros: backquote ("`") and LET.
The "backquote" macro and the LET macro will be autoloaded when used.
...
The LET macro provides a convenient way to lambda-bind variables to
values. Its usages is as follows:
(LET ((var1 val1) (var2 val2) . . . (varn valn))
<form1>
. . .
<formn>)
One may substitute merely "var" in place of "(var NIL)"
For example:
(LET ((A 1) (B 2) C)
<forms>)
Binds A to 1, B to 2, and C to NIL and then evaluates <forms>.
(let ((a 1) (b 2) (c 3) (d 4))
(list a c))
(destructuring-bind (a b c d) '(1 2 3 4)
(list a c))
(match '(1 2 3 4)
[(a b c d) (list a c)])
while the above destructuring-bind
and match
could be rewritten to the equivalent let
, i'm not sure the same is true for the cases below
(destructuring-bind (a (b c) &rest d) '(1 (2 3) 4)
(list a c))
(match '(1 2 3 4)
[(a (b c) d ...) (list a c)])
> 23
yeah modern LET is insufficient, i was just pointing out that "using functions" is the og way of binding variables. it's the lambda calculus way and the little schemer kind of books like to introduce lambda-binding, but i personally didn't realize that it wasn't just some theoretical curiosity. it was used as the only method until someone invented LET macro.
there's actually a part in the second sept 17th quote that i skipped, because i didn't want to complicate the discussion,
An extension to the binding of one variable, is a "pattern" of
variables, which are bound to the corresponding subparts of the
"val"; e.g., (LET ( ((A . B) '(CONS 1 2)) ((C () D) (LIST 1 2 3)))
<forms>)
would bind A to "CONS", B to "(1 2)", C to "1", and D to "3".
so you could write your last destructuring-bind as
(let ( ((a (b c) . d) '(1 (2 3) 4)) )
(list a c))
at some point there must've been a conscious decision made to make LET less powerful. maclisp also had destructuring in DEFUN arguments, so you could have monstrocities like (defun f ((w x) &optional ((y . z))). but both LET and DEFUN destructuring are already missing in zeta lisp
>>24
that's interesting lore, i didn't know earlier lisps had that (useful) feature and will read more, this seems to restore defun destructuring:
(defmacro destructfun (name pattern &rest forms)
(let ((list (gensym)))
`(defun ,name (&rest ,list)
(destructuring-bind ,pattern ,list
,@forms))))
(destructfun add (((a . b) (c . d) . rest))
(declare (ignorable a c rest))
(+ b d))
(add '((a . 1) (b . 2) (c . 3)))
lisp news
where do you read these?
> 25
or you can do it the naggum way, and define your own common-lisp base package, with DEFUN and LET shadowed to more elaborate versions. if you're sufficiently tasteful in your extension, you can even make it backwards compatible.
> 26
http://ml.cddddr.org/lispnews/
http://www.avanthar.com/healyzh/_info_/lisp.news
https://www.saildart.org/LISP.RPG%5BUP,DOC%5D
>>28
nice, thanks /prog/rider