Wish list

For the Compleat Fan
xytroxon
Posts: 296
Joined: Tue Nov 06, 2007 3:59 pm
Contact:

Re: Wish list

Post by xytroxon »

Funambulistic* Object Oriented Programming

* A "funambulist" is a tightrope (or slack rope), walker or dancer...

Image

Damià Timoner's "El Funàmbul" (2007)
("El Funàmbul") contains 10 instrumental pieces; 5 new Damià composicions and 5 covers from different bands as famous as The Doors, Nirvana, Depeche Mode, adapted to the Spanish guitar sound.
Reminds me of Lutz and newLISP, classical approach, yet so avant-garde ;p>

-- xytroxon
"Many computers can print only capital letters, so we shall not use lowercase letters."
-- Let's Talk Lisp (c) 1976

kks
Posts: 13
Joined: Sat Dec 26, 2009 12:05 am

Re: Wish list

Post by kks »

As for new FOOP, is `self` a function or a list? And how can I use association list for fields? In old FOOP, I can do:

Code: Select all

(define (C:C x y) (list C (list 'x x) (list 'y y)))
(define (C:p o) (println "x=" (lookup 'x o) "; y=" (lookup 'y o)))
(:p (C 1 2))   # x=1; y=2
By the way, is it a good idea if newLISP extends `nth` to call `lookup` for non-number indices? (Another wish ;-)

Code: Select all

(setq L '((a 1) (b 2) (c (d 3))))
(list (L 'a) (L 'c 'd) (L 2 'd))   # => (1 3 3)
And when an index is out-of-bound, why not `nth` just return nil instead of throwing an error? I found that I usually need to check the length of the list first.

Code: Select all

(setq L '(a b (c d))
(L 1)   # => b
(L 5)   # ERR: list index out of bounds
(and (> (length L) 5) (L 5))   # => nil
(and (> (length L) 2) (> (length (L 2)) 1) (L 2 1))   # => d
Currently, I just do:

Code: Select all

(define (nth? Idx Seq (Default))
	{like nth, but return Default if Idx is out of bound or Seq is not a sequence}
	(let (R)
		(if (catch (nth Idx Seq) 'R) R
			(find "index out of bounds|list expected" R 0) Default
			(throw-error R) )))
(nth? 5 L)   # => nil
(nth? '(2 1) L)   # => d
But as you see, isn't just (L 5) better than (nth? 5 L)?

By the way, could someone please tell me how to have newLISP's readline history across sessions?

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: Wish list

Post by Lutz »

As for new FOOP, is `self` a function or a list?
its a function:

(self 1) is equivalent to ((self) 1)

without any argument it returns the object list, with arguments it indexes the object list.

There is a chapter about objects and associations in the manual:

http://www.newlisp.org/downloads/develo ... .html#foop

You also can use predefined indexes and index vectors:

Code: Select all

(new Class 'Person)

(context Person)

(constant 'age 1)
(constant 'height '(2 0))
(constant 'weight '(2 1))

(define (set-weight w)
	(setf (self weight) w))

(context MAIN)

(set 'joe (Person 35 '(1.75 165)))
;; or because its all constants
(set 'joe '(Person 35 (1.75 165)))

(joe Person:weight) => 165

(:set-weight joe 180)

(joe Person:weight) => 180
And when an index is out-of-bound, why not `nth` just return nil instead of throwing an error? I found that I usually need to check the length of the list first.
This would create ambiguities with the following case:

Code: Select all

(set 'l '(a b nil c d nil))
(l 2) -> nil
(l 5) -> nil
use a negative index to count from the end:

Code: Select all

(set 'l '(a b c d e f g))
(l -2) => f
see also here:

http://www.newlisp.org/downloads/develo ... l#indexing

m i c h a e l
Posts: 394
Joined: Wed Apr 26, 2006 3:37 am
Location: Oregon, USA
Contact:

Re: Wish list

Post by m i c h a e l »

Lutz wrote:You also can use predefined indexes and index vectors:
This is how I've been defining my objects lately. It not only makes clear which attribute you are referring to, but it also allows you to freely add or reorder an object's attributes without needing to change any of its methods. As the complexity of an object grows, so does the need for named indexes. Together, self and setf act as an object's getters and setters.

m i c h a e l

xytroxon
Posts: 296
Joined: Tue Nov 06, 2007 3:59 pm
Contact:

Re: Wish list

Post by xytroxon »

Lutz wrote:
And when an index is out-of-bound, why not `nth` just return nil instead of throwing an error? I found that I usually need to check the length of the list first.
This would create ambiguities with the following case:

Code: Select all

(set 'l '(a b nil c d nil))
(l 2) -> nil
(l 5) -> nil
That code is somewhat confusing (lowercase "L" looks like the number one "1" on my browser)... And the indexing problem is not shown clearly...

Code: Select all

(set 'lst '(a b nil c d nil))
(lst 2) -> nil
(lst 4) -> d
(lst 5) -> nil
; without index bounds checking
(lst 6) -> nil
; with index bounds checking
(lst 6) -> ERR: list index out of bounds
Flagging an invalid index value is not an inconvenience... It is a responsible language practice... And it helps ensure code reliability... Not knowing that an index is sometimes out of range can easily hide a buggy program design that works most of the time...

-- xytroxon
"Many computers can print only capital letters, so we shall not use lowercase letters."
-- Let's Talk Lisp (c) 1976

kks
Posts: 13
Joined: Sat Dec 26, 2009 12:05 am

Re: Wish list

Post by kks »

Thanks Lutz for clarifications

Kazimir Majorinc
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia
Contact:

Re: Wish list

Post by Kazimir Majorinc »

I think kks's proposal for (nth L 100000...) = nil is not unreasonable. It is analogous to

(1) Previously undefined variables, if used for first time, have value nil
(2) Some functions, for example, find or exists return nil if they cannot return value caller asked for.

Ambiguity, however, exists. For example, if function call:

(exists (lambda(x)(not (integer? x))) L)

returns nil, we cannot be sure whether L actually contains nil, or it contains only integers.

But, what caused the problem? In my opinion, problem is in function exists which returns two information compressed in one value. One information is: is there any non-integer in L? Other information is - if there is non-integer in L, which one is that? In most cases, we can compress these two information, but if that non-integer is the same value we use to inform that all members of L are integers, we're lost.

Why we readily use such compression? Because if it works correctly, and it does in most of the cases, it is handy. Our programs are shorter and simpler. But, once we discovered that it doesn't work correctly in all cases, we shouldn't ignore it. Such imprecisions and ambiguities accumulate, and result in short, but not very understandable programs. What is the correct way out of that? I think that for all such ambiguous, lossy functions need lossless version. For example,

(exists/losless (lambda(x)(not (integer? x))) L)

should return (true nil) if nil is element of L, and (nil) if there is no non-integer elements in L.

Beside that, it is maybe best to keep lossy versions as they are, because these are handy and because of compatibility. Maybe. "Default" version might be either one.

Back to kks's proposal, I think both nth/lossy and nth/lossless have sense.

kks
Posts: 13
Joined: Sat Dec 26, 2009 12:05 am

Re: Wish list

Post by kks »

Or, like `lookup`, adding a parameter to `nth` for a "default value" to return in case an index is out of bounds:

Code: Select all

(nth 5 '(1 2 3) 0)   # => 0
But Kazimir's suggestion is more general, in case we don't know a value that would never exist in the list.

JeremyDunn
Posts: 11
Joined: Wed Apr 07, 2010 12:18 am

Re: Wish list

Post by JeremyDunn »

Thought I would get this thread going again with some more simple things that we might do to jazz things up.

1. I also put my vote in for Kazimir's operators +. and such. They look better and are easier to read.

2. I would like to see some of the math functions overloaded to do common vector operations. For instance, if vec
is a vector (a list of integers or floats):

(+ vec) returns (apply + vec)
(add vec) returns (apply add vec)
(* vec) returns (apply * vec)
(mul vec) returns (apply mul vec)
(pow vec) returns (apply add (map mul vec vec)) ;the sum of squares
(pow vec n) returns (i1^n + i2^n + .... + iN^n) the sum of the nth power of the elements
(sqrt vec) returns (sqrt (pow vec)) ;the vector norm
(div vec) returns the unit vector vec/norm

The cost of adding these is minimal but the gain for vector math is great in that we can use conventional functions
instead of a plethora of new ones. Vector expressions will also be greatly simplified.

Locked