Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - ghfischer

#1
newLISP newS / A custom push-assoc
May 03, 2008, 01:02:31 PM
During the assoc discussion I came across a problem I'm sure I knew how to solve a year or two ago, but I can't figure out anymore.



I know I'll only have assoc lists of the form
((a (1 2)) (b (3 4)) ...)

I want to write a function like
(push-assoc key value assoc-lst)

The only way I could get it to work is if I instead had a global assoc-lst that I used.

(set 'alst '())
(define (push-assoc k v )
  (if (lookup k alst)
    (assoc-set (alst k) (list k (append (last $0) (list v))))
    (push (list k (list v)) alst -1)))


Any suggestions on how to make this so I can pass in the assoc-lst ?

I tried using a define-macro but failed.

I think I'm just missing something obvious.
#2
newLISP newS /
April 20, 2008, 08:30:26 AM
I'm of the opinion that char should move from strings to integers and not introduce nil.  I think the empty string is a valid special case where 0 should be returned.



That being said I'm ok with char returning errors if the offset is out of bounds.  I'd argue that any argument to the offset for an empty string should be an out of bounds error - but looking at the code it seems easier to just make offset=0 a special case rather that test offset for nil.



0 is a valid character in the ascii set, it's the nul character.

So if (char 0) --> "00" then (char "00") --> 0.

"" is simply shorthand for "00".
#3
newLISP newS / A temporary patch.
April 19, 2008, 12:57:59 PM
In nl-string.c change line 219 from


offset = adjustNegativeIndex(offset, len);

to


if ((offset != 0) || (len > 0)) offset = adjustNegativeIndex(offset, len);

This will produce the following behavior:

newLISP v.9.3.8 on OSX IPv4 UTF-8, execute 'newlisp -h' for more info.

> (char "")
0
> (char "" 0)
0
> (char "" 1)

string index out of bounds in function char
> (char "" -1)

string index out of bounds in function char
> (char "a")
97
> (char "a" 1)

string index out of bounds in function char
> (char "a" 0)
97
> (exit)

#4
newLISP newS /
March 30, 2008, 12:34:47 PM
Good point on the apply consequence.



Imagine you have a scheduled report to run at 7am every day.  Since you're in a timezone that does daylight savings for a portion of the year the report should run at 7am GMT and for another portion at 8am GMT.



But as a user, I don't care about any of that - I want my report at 7am every day and I want the computer to figure out when exactly that is in GMT.



It looks like this will be a bit harder problem to solve since detecting whether I'm in daylight savings time differs per platform.
#5
newLISP newS / Another quick thought.
March 30, 2008, 10:38:40 AM

> (date (date-value) 0 "%Y %m %d %H %M %S")
"2008 03 30 12 32 58"
> (date (date-value 2008 3 30 12 32 58) 0 "%Y %m %d %H %M %S")
"2008 03 30 07 32 58"


To me these two functions should return the same value.



Lutz - Perhaps you could add another option onto (date-value)



syntax: (date-value int-year int-month int-day [int-hour int-min int-sec])
syntax: (date-value int-year int-month int-day [int-hour int-min int-sec] [int-offset])


If int-offset is NULL just do the conversion based upon timezone like it's being done in (date-value).  If int-offset is non-null then the programmer is asking for the raw GMT value.
#6
I'm working on adding some date syntactic sugar for newlisp.  Inspired by the ease of use of certain date manipulation in Ruby.



During my tests I noticed what i think is an issue in some of the date routines related to offset or possibly daylight savings time.  I tried to implement a newlisp version of http://snippets.dzone.com/posts/show/2099">days_in_month.



(Note: I'm in Austin, TX CDT which means my GMT offset is -0500 ==> 300 offset)



(Also note that if I use (date-value) without any options I don't need to specify an offset to get the correct datetime)


newLISP v.9.3.5 on OSX IPv4 UTF-8, execute 'newlisp -h' for more info.

> (date (date-value 2008 1 1) 300 "%Y %m %d")
"2007 12 31"
> (date (date-value) 0 "%Y %m %d"))
"2008 03 30"


Playing around a bit I found this


> (date (date-value) 300 "%z")
"-0500"
> (date (date-value 2008 3 1 0 0 0) 300 "%d")
"29"
> (date (date-value 2008 3 1 0 0 1) 300 "%d")
"29"
> (date (date-value 2008 3 1 1 0 0 ) 300 "%d")
"01"


It looks like there's some issue that can be solved by adding an hour.

Upon further investigation I found this


> (date (date-value 2008 4 1) 300 "%Y %m %d")
"2008 04 01"


That made me think - Daylight Savings Time issue (March 9th)


> (date (date-value 2008 3 8) 300 "%Y %m %d")
"2008 03 07"
> (date (date-value 2008 3 9) 300 "%Y %m %d")
"2008 03 08"
> (date (date-value 2008 3 10) 300 "%Y %m %d")
"2008 03 10"
> (date (date-value 2008 3 9 1 0 0) 300 "%Y %m %d")
"2008 03 09"
> (date (date-value 2008 3 8 1 0 0) 300 "%Y %m %d")
"2008 03 08"


It looks like doing historical date conversion doesn't take into consideration daylight savings time.  Also notice that I can't get access to what the timezone was before March 9th and adjust the offset accordingly.



My hackish workaround is to take the time at 3am.  

But I'm hoping there's a better way.  

So finally ... here's a newlisp days-in-month
(define (days-in-month y m)
  (set 'tmp (date (date-value) 0 "%z"))
  (set 'offset (+ (* (int (1 2 tmp)) 60) (int (3 2 tmp))))
  (if (= "+" (0 1 tmp)) (set 'offset (* -1 offset)))
  (int (date (date-value y (+ m 1) 0 3 0 0) offset "%d"))
)
> (days-in-month 2008 2)
29
> (days-in-month 2007 2)
28
> (days-in-month 2008 3)
31
> (days-in-month 2008 4)
30
#7
Anything else we might add? / Arc -- meh.
January 30, 2008, 12:41:08 PM
I read through the arc tutorial and am thoroughly unimpressed.



Most of the stuff I like newLISP already has, and there's no mention of any integrated web stuff (like net-* or *-url).



The one interesting feature I thought might be useful to put in newLISP is some version of Arc's uniq macro functionality.  Quoting in full


QuoteThe way to fix repeat is to use a symbol that couldn't occur in

source code instead of x.  In Arc you can get one by calling the

function uniq.  So the correct definition of repeat (and in fact

the one in the Arc source) is



(mac repeat (n . body)

  `(for ,(uniq) 1 ,n ,@body))



If you need one or more uniqs for use in a macro, you can use w/uniq,

which takes either a variable or list of variables you want bound to

uniqs.  Here's the definition of a variant of do called do1 that's

like do but returns the value of its first argument instead of the

last (useful if you want to print a message after something happens,

but return the something, not the message):



(mac do1 args

  (w/uniq g

    `(let ,g ,(car args)

       ,@(cdr args)

       ,g)))


I've always been ok with using leading underscores, but I could see the use in being able to use syntactic sugar like the following ...


(define-macro (foobar (m-uniq x y)) (set x (eval y)))

My $0.02
#8
Anything else we might add? /
December 13, 2007, 11:05:50 AM
Quote from: "cormullion"a little too short


I also noticed that in 9.2.5 or higher I can make it even shorter! :)


(define (natural-key s)
  (filter if (flat (transpose (list (parse s "[0-9]+" 0) (map int (find-all "[0-9]+" s)))))))
#9
Anything else we might add? / Better example.
December 13, 2007, 08:24:42 AM
Good point Lutz.  I should have provided a better example.



Here's the basic case
> (natural-sort '("a10" "a2" "a1" "a14"))
("a1" "a2" "a10" "a14")
> (sort '("a10" "a2" "a1" "a14"))
("a1" "a10" "a14" "a2")


and the embedded case
> (natural-sort '("i30z" "i3n" "i20n" "i18z"))
("i3n" "i18z" "i20n" "i30z")
> (sort '("i30z" "i3n" "i20n" "i18z"))
("i18z" "i20n" "i30z" "i3n")


Of course there's always the edge cases ...
> (natural-sort '("i1" "i03" "i5"))
("i1" "i03" "i5")
> (sort '("i1" "i03" "i5"))
("i03" "i1" "i5")


To me having the zero first seems better.  But to most non-programmers it doesn't.  Hopefully whatever you're sorting in this case will have consistency on leading zeroes.
#10
Anything else we might add? / A short helper.
December 13, 2007, 06:43:01 AM
Although not a complex piece of code, the following is quite useful when you have to sort lists the way most real people think of sorting.



(define (natural-key s)
  (set 'strs (parse s "[0-9]+" 0))
  (set 'nums (find-all "[0-9]+" s))
  (if nums (set 'nums (map int nums)) (set 'nums '()))
  (filter if (flat (transpose (list strs nums))))
)

(define (natural-sort l)
  (sort l (fn (x y) (< (natural-key x) (natural-key y))))
)

(set 'foo '("i19n" "i17n" "z40" "40a" "50" "foo" "z4000" "z30"))

(natural-sort foo)


which returns



("40a" "50" "foo" "i17n" "i19n" "z30" "z40" "z4000")


Based on http://nedbatchelder.com/blog/200712.html#e20071211T054956">Human Sorting
#11
newLISP newS / newLISP on Noodles with Nettles
January 03, 2007, 04:21:56 PM
http://newlisp-on-noodles.org/wiki/images/3/3e/Nettlepasta.jpg">



I just released a module for working with the nettle cryptographic library.



http://newlisp-on-noodles.org/wiki/index.php/Nettles">http://newlisp-on-noodles.org/wiki/index.php/Nettles



Enjoy!



PS - I haven't been able to get it to work on Mac OS X. Nettle is in Fink but there's no dylib. If anyone knows how to make libnettle.dylib from libnettle.a I'd appreciate a tutorial in converting. For now it's been tested with Linux only.
#12
newLISP newS / Noodles
November 01, 2006, 01:11:36 PM
johnd and I have decided to publicly release the newLISP on Noodles wiki



http://www.newlisp-on-noodles.org">http://www.newlisp-on-noodles.org



In a nutshell, we want Noodles to be the "Ruby on Rails" of newLISP.



Right now we've got a few place holders for library and module development and some tips 'n' tricks.



Enjoy.



Gord
#13
newLISP in the real world / Use map.
January 13, 2006, 12:02:19 PM

> (set 'a '())
()
> (set 'b '("this" "that"))
("this" "that")
> (map (fn(x) (push x a)) b)
("this" "that")
> a
("that" "this")


This will push every element in b onto a.
#14
newLISP in the real world / fork and sleep
May 10, 2005, 04:09:20 PM
Can someone explain to me why the following code does not sleep 5 seconds?

I have a hunch that a signal from the forked child invalidates the sleep - but I have no proof.

(define (SleepMe x)
  (println "Starting...")
  (fork (dotimes (y 10) (println y)))
  (sleep (* x 1000))
  (println "Why do you not sleep?")
)

(SleepMe 50)


Gord