cond and if

Started by frontera000, September 26, 2006, 01:50:54 PM

Previous topic - Next topic

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?

Lutz

#1
do you mean this?


>  ((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

frontera000

#2
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 : "lambdan"

Lutz

#3
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:


> (lambda)
(lambda )
>


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:


> (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.


> (empty? (lambda))
true
> (lambda? (lambda))
true


Lutz

frontera000

#4
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

Lutz

#5
By definition there cannot be implicit indexing for (lambda). The following example shows why:


> ((lambda (x) (+ x x)) 1)
2
>


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:


> (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.

frontera000

#6
Thank you. I think slicing works for me.

Jeremy Dunn

#7
As long as we're talking about conditional statements I would like to offer the following:



;;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?

Lutz

#8
You could do:


> (set 'n 2)
> (eval (nth n '("zero" "one" "two" "three")))
"two"
>


Lutz

cormullion

#9
Quote from: "Jeremy Dunn"
(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 ....

Jeremy Dunn

#10
Quote from: "Lutz"You could do:


> (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.

Lutz

#11
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:
(set 'L '((1 "one") (2 "two") (3 "three")))

so you can just do:
(assoc n L)
; or
(lookup n L)


on it. Or when you already have two different lists for constants and expressions:


(lookup 2 (map list '(1 2 3) '("one" "two" "three"))) => "two"


Lutz