Wish list

Started by kks, January 15, 2010, 01:40:43 PM

Previous topic - Next topic

xytroxon

#15
Quote from: "kks"
xytroxon,

In my opinion, I think #{...}# is better than #|...|#, because it's easier to match the end of comment by using `%` in vim.


I'ld like to see something like (== for the equality test and (= for (set (setq and (:= for (setf, but precedent tends to limit what you can do now and would be confusing to those coming from other Lisps.



Likewise, #|...|# is the block comment form for Common Lisp, hence is more likely to be recognized/expected by Lispers and Schemers, and be recognized by editors highlighting parser...



The Schemer's in-line comment is useful when experimentally trying out two forms of a function, especially if they have long argument lists.



(s-exp1 #;(s-exp2a ...) (s-exp2b ...) ...)



But editors are less likely to properly terminate the highlighted inline comment...



-- xytroxon
\"Many computers can print only capital letters, so we shall not use lowercase letters.\"

-- Let\'s Talk Lisp (c) 1976

anta40

#16
Quote from: "Kazimir Majorinc"
(I'd repeat my old proposal for +., *. etc for floating point +, * etc.)


like ocaml, right?

TedWalther

#17
I like the proposed #; and #| comment forms, because of their compatibility with existing syntax hilighters.  #; particularly has me excited.



As for Kazimirs +. ++. forms, those can be done as constants, right?  I sort of liked the FORTRAN feel of add, sub, mul, etc.



For the == instead of =, I must disagree.  Personally I have started using unicode characters in my code; for setf I use the unicode left-arrow character.  For "and" and "or" and "find" I use some of the operators from set logic. UTF8 support is GREAT!



When I am doing trig, it is SOOO nice to be able to name variables "phi" and "theta", and be able to use the actual Greek letter instead of having to spell it out!



Yes, I had to configure vi a tiny bit to make it do auto-substitutions of some key sequences into their UTF8 form, but it leads to beautiful looking code.



Ted
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

TedWalther

#18
For any who may be interested, here is my init.lsp.  It shows the beautiful things you can do now that we have UTF8 support!



; Standard C/Unix filehandles that are open on startup
(constant
  (global 'stdin) 0
  (global 'stdout) 1
  (global 'stderr) 2)

(define (dirname path) (join (chop (parse path "/|\\" 0)) "/"))
(define (basename path) (last (parse path "/|\\" 0)))

; Some arithmetic functions
(constant
  (global 'negative?) <
  (global 'positive?) >)
(define (divisible? i j) (= (mod i j) 0))

(constant
  (global 'pi) (mul 4 (atan 1))
  (global 'radians/degree) (div pi 180)
  (global 'degrees/radian) (div 180 pi))
(define (radians deg) (mul deg radians/degree))
(define (degrees rad) (mul rad degrees/radian))

(constant (global 'do) begin)

; union 222a intersection 2229
(constant '≠ !=)        # 2260 not equal
(constant '≡ =)         # 2261 identical to
(constant '∈ find)      # 2208 element of
(constant '≤ <=)        # 2264 less than or equal
(constant '≥ >=)        # 2265 greater than or equal
(constant '∀ dolist)    # 2200 for all
(constant '× mul)       # 00D7 multiply
(constant '÷ div)       # 00F7 divide
(constant '√ sqrt)      # 221A square root
(constant '⌈ ceil)      # 2308 integer ceiling
(constant '⌊ floor)     # 230A integer floor
(constant '⋀ and)       # 22C0 n-ary logical and
(constant '⋁ or)        # 22C1 n-ary logical or
(constant '⟵ setq)      # 27F5 assignment
(constant '¬ not)      # FFE2,00AC logical not
(constant '⋂ intersect) # 22C2 set intersection
(constant '⋃ append)    # 22C3 set union

(define (∑ lst)      # 2211 n-ary summation
  (apply add lst))
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

m i c h a e l

#19
Hi cormullion!



The operative word in my example is "simulating" ;-) Lutz would have to implement it properly to have the correct effect.



I've been quietly working on exploring FOOP (especially the new mutability!) and putting together another video. Hope to have something to share in the near future.



m i c h a e l

Lutz

#20
Quote... and putting together another video


thanks Michael, for taking care of this! I hope the last fixes for 'self' work for all situations one might encounter. The test routines you emailed me have been appended the modified qa-foop file (v10.1.9).



FOOP is ready for primetime now!



... and still functional enough to call it FOOP :)



ps: several suggestions in this thread have been implemented and we will have another development release before 10.2.

cormullion

#21
Lutz - I'm currently using both FOOP version 0 and FOOP version 1. v0 works for current stable releases, v1 works for curent development releases. Eg http://unbalanced-parentheses.nfshost.com/dragonfly_twitter">//http://unbalanced-parentheses.nfshost.com/dragonfly_twitter is using v0 because NFS is on v0 (ie 10.1).



Is there a way to add compatibility to v1 to work with v0? Or a way to define things so that allow the newLISP installation can be upgraded without me having to write separate versions of the FOOP file?

m i c h a e l

#22
Quote from: "Lutz"thanks Michael, for taking care of this!


You're welcome! I'm very happy to help in my small way.


Quote from: "Lutz"I hope the last fixes for 'self' work for all situations one might encounter.


I've been really exercising self quite a bit lately. It's performing brilliantly. Feels very natural for both newLISP and programming with objects.


Quote from: "Lutz"and still functional enough to call it FOOP :)


I keep meaning to ask you something, Lutz. When you say:


Quote from: "Lutz"The fact that each object in FOOP is the functional expression which generates itself - its own constructor expression - still justifies the 'F' in FOOP.


It makes me wonder if having constructors with default arguments breaks with this:


> (new Class 'Point)
Point
> (define (Point:Point (x 0) (y 0)) (list (context) x y))
(lambda ((x 0) (y 0)) (list (context) x y))
> (Point)
(Point 0 0)
> _


Or is the fact that (Point) always gives us (Point 0 0) what makes it functional?



What I do know is that coding in FOOP has been more fun than programming in traditional object-oriented languages. So FOOP may as well stand for Fun Object-Oriented Programming! Or another F-word when I can't get the damn code to work ;-)



m i c h a e l

Lutz

#23
Yes, when you modify the default constructor functional analogy of object<->construtor is somewhat different, but not broken. Then there is also the new (self) a Function to reference the target object of the message.


QuoteFun Object-Oriented Programming


We also could invent some sort of tag-line including both the word Fun and Functional and leaving the interpretation open to the public?



Regarding old/new FOOP compatibility. I don't see an easy automated way, but at least it is easy to port from old to new by simply renaming the object parameter in old FOOP code to 'self':



; old FOOP code original
(define (method obj p1 p2)
...
(... (obj 1) ...)
)

; old FOOP code prepared for upgrade
(define (method self p1 p2)
...
(... (self 1) ...)
)

; new FOOP code after taking ode self from the parameter list
(define (method p1 p2)
...
(... (self 1) ...)
)


Of course this doesn't take advantage of object mutability, which enables shorter and faster code for modifying objects. But at least old code can quickly be prepared and made work for the switch-over to a newer newLISP version.



I would probably just code two sections (or even files): one for old, one for new FOOP and then decide by the version number in 'sys-info'.

m i c h a e l

#24
Quote from: "Lutz"We also could invent some sort of tag-line including both the word Fun and Functional and leaving the interpretation open to the public?


I think FOOP is as much about fun as it is about fitting gracefully into a functional language. I'm delighted by how well FOOP blends with newLISP. And besides, functional has another meaning that might be the most appropriate yet:


Quotedesigned to be practical and useful, rather than attractive.


Of course, I find FOOP attractive, too, but it's definitely practical and useful. The complexity of the object models I've done in newLISP blows away anything I've managed to accomplish in other languages.



Leaving it open to interpretation is fine by me. A rose by any other name . . .


Quote from: "Lutz"but at least it is easy to port from old to new by simply renaming the object parameter in old FOOP code to 'self'


This is ingenious, Lutz.



Back to FOOPin',



m i c h a e l

xytroxon

#25
Funambulistic* Object Oriented Programming



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



http://www.damiatimoner.com/images/el_funambul_gran.jpg">



http://www.damiatimoner.com/eng/el_funambul.htm">Damià Timoner's "El Funàmbul" (2007)


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

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

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

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

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

(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

#27
QuoteAs 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/development/newlisp_manual.html#foop">http://www.newlisp.org/downloads/develo ... .html#foop">http://www.newlisp.org/downloads/development/newlisp_manual.html#foop



You also can use predefined indexes and index vectors:
(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


QuoteAnd 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:


(set 'l '(a b nil c d nil))
(l 2) -> nil
(l 5) -> nil

use a negative index to count from the end:



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


see also here:



http://www.newlisp.org/downloads/development/newlisp_manual.html#indexing">http://www.newlisp.org/downloads/develo ... l#indexing">http://www.newlisp.org/downloads/development/newlisp_manual.html#indexing

m i c h a e l

#28
Quote from: "Lutz"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

#29
Quote from: "Lutz"
QuoteAnd 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:


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


(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