Page 1 of 1
cond and if
Posted: Tue Sep 26, 2006 8:50 pm
by frontera000
cond and if seem to work differently:
> ((lambda (x) (if (= (x 0) 'quote) (print "found") (print "not"))) '(quote a))
> found"found"
But
> ((lambda (x) (case (x 0) ('quote (print "found")) (true "not"))) '(quote a))
>"not"
why is this?
Posted: Tue Sep 26, 2006 9:11 pm
by Lutz
do you mean this?
Code: Select all
> ((lambda (x) (if (= (x 0) 'quote) "found" "not")) '(quote a))
"found"
> ((lambda (x) (cond ( (= (x 0) 'quote) "found") "not")) '(quote a))
"found"
>
if you mean 'cond' it works Ok, if you use 'case' then remember that the switching value must be a constant, 'case' does not evaluate the first parameter.
Lutz
Posted: Tue Sep 26, 2006 9:33 pm
by frontera000
Thanks.
My mistake.
How about:
((lambda (x) (if (= (x 0) 'lambda) "found" "not")) '(lambda a))
> <40B99D>
> <40B99D>
invalid lambda expression : "lambda) \"found\" \"not\")) '(lambda a)) \n"
It seems quoting lambda is not possible.
> 'lambda
invalid lambda expression : "lambda\n"
Posted: Tue Sep 26, 2006 9:54 pm
by Lutz
Yes,
lambda in newLISP is not a keyword like a built-in function or operator, but a special attribute of a list: a
lambda list, so it could occur like this:
As you can see, a lambda list evaluates to itself in newLISP and you don't need to quote it when using it as a parameter to another function.
When constructing lambda lists with 'append' or 'cons' then 'append' associates the lambda property to the right and 'cons' to the left:
Code: Select all
> (append (lambda) '((x) (+ x x)))
(lambda (x) (+ x x))
> (cons '(x) (lambda (+ x x)))
(lambda (x) (+ x x))
>
The 'cons' example shows you that lambda is
not the first element of a list but rather a property of that list.
Code: Select all
> (empty? (lambda))
true
> (lambda? (lambda))
true
Lutz
Posted: Tue Sep 26, 2006 10:07 pm
by frontera000
Thanks. I kind of remember reading that in the manual somewhere.
How about implicit indexing.
> (nth 0 '(a b c))
a
> ('(a b c) 0)
a
>
This is fine. But...
> (nth 0 '(lambda (x) a b c))
> <40B99D>
(x)
> ('(lambda (x) a b c) 0)
nil
Posted: Tue Sep 26, 2006 10:37 pm
by Lutz
By definition there cannot be implicit indexing for (lambda). The following example shows why:
lambda is used in an
applicative context/situation. Implicit indexing is giving lists or numbers functionality when using in an applicative context. For lambda expression this applicative functionality is already defined as applying the lambda expression to the arguments following it.
But there is implicit slicing for lambda:
Code: Select all
> (1 (lambda (x) (+ x x)))
((+ x x))
> (0 1 (lambda (x) (+ x x)))
((x))
>
because now the lambda list can be treated just like a normal list.
Lutz
ps: note that quoting lambda is not necessary, as lambda evaluates to itself.
Posted: Tue Sep 26, 2006 11:11 pm
by frontera000
Thank you. I think slicing works for me.
Posted: Sat Sep 30, 2006 11:12 pm
by Jeremy Dunn
As long as we're talking about conditional statements I would like to offer the following:
Code: Select all
;;This function provides a variation of the CASE function.
;;
;; (case n
;; (2 "two")
;; (3 "three")
;; (4 "four")
;; (t "default")
;; )
;;
;; you could write this as
;;
;; (choose n '(2 3 4) '("two" "three" "four" "default"))
;;
;;
(define (choose tst match dolst , len1 len2 n)
(setq len1 (length match) len2 (length dolst))
(if (member len2 '(len1 (+ 1 len1)))
(eval (if (setq n (find (eval tst)(map eval match)))
(dolst n)
(last dolst)))))
The advantage of the CHOOSE function over the CASE function is that in the CASE function you must add two parentheses for every condition you add. Whereas in the CHOOSE function the number of parentheses remains constant. The other advantage is that for long CASE statements the CHOOSE layout is often much more compact. Any chance of seeing something like this in NewLisp?
Posted: Sun Oct 01, 2006 2:42 am
by Lutz
You could do:
Code: Select all
> (set 'n 2)
> (eval (nth n '("zero" "one" "two" "three")))
"two"
>
Lutz
Posted: Sun Oct 01, 2006 8:21 am
by cormullion
Jeremy Dunn wrote:Code: Select all
(choose n '(2 3 4) '("two" "three" "four" "default"))
Any chance of seeing something like this in NewLisp?
I like that syntax - seems very elegant somehow. But easy enough to define too? I can see that deciding whether to add all these ideas to the language is a tough call - you don't want to have to define all your favourite control flow expressions at the top of every file, yet you don't want to swell the language by adding stuff that's easily defined. Yet our code becomes less portable if we all rely on our custom versions of the language. Although that's what newLISP is good at, so ....
Posted: Sun Oct 01, 2006 3:56 pm
by Jeremy Dunn
Lutz wrote:You could do:
Code: Select all
> (set 'n 2)
> (eval (nth n '("zero" "one" "two" "three")))
"two"
>
Lutz
Yes, this example was probably not the best. But if I was comparing to expressions or something other than integers the Choose structure would be more efficient. Like Cormullion says it is often a tough call as to what is important but I felt that control structures are part of the core grammar of a language and new forms at least deserved to be looked at. We have UNLESS in the language even though it only saves us one set of parentheses. I presume it exists for the convenience of our human brains rather than logical neccessity. The Choose structure occurs many times also and usually saves far more parentheses than 2. Perhaps you could put function suggestions into a list and every 6 months or so we could have a survey of how many people think a given idea is worth considering. Maybe we even need a new forum page devoted to function suggestions/modifications so that they are all in one spot.
Posted: Sun Oct 01, 2006 5:42 pm
by Lutz
The advantage of the 'case' syntax is that it makes very clear what constant belongs to what expression.
When 'choose' would have bigger 2 lists of constants and expressions, it will be difficult for the eyes to see the correspondence of the too. The same would be true if the expressions pointed too are more complex and not just string constants.
Another consideration is, that the second part of the 'case' expression is really an association list:
Code: Select all
(set 'L '((1 "one") (2 "two") (3 "three")))
so you can just do:
on it. Or when you already have two different lists for constants and expressions:
Code: Select all
(lookup 2 (map list '(1 2 3) '("one" "two" "three"))) => "two"
Lutz