(archive 'newLISPer)

December 31, 2007

Vote for somebody!

Filed under: newLISP — newlisper @ 10:11

2007 has been a great year for newLISPers! We’ve seen a new graphics toolkit, two major releases (9.1 and 9.2), a movie trilogy, two objected-oriented frameworks, a superfast editor written in newLISP, a newlispweb web framework, the newLISP fan club wiki, a brace of new bloggers, and lots of good code from some skilled programmers.

I also managed to write a bit of code this year, including this blogging engine (the LamdbaPress), various GUI apps, source-code formatting, a port of Markdown (I never want to look at that code again!), and a TEX to HTML translator that produces the Introduction to newLISP (which is kindly hosted at newlisp.org. None of this code would win any prizes for elegance or idiomatic Lispiness (or even reliability); but we all do what we’re best at!

However, there are prizes to be won: don’t forget to vote for some of the elegant and ingenious entries in the newLISP 2007 competition. You have a few more days to vote…

And if you didn’t get round to submitting an entry for this year’s competition, get coding for the 2008 competition!

As ever, a big thanks to Lutz and everyone in the newLISP community for your contributions over the year. 2007 has been fun.

Now for 2008!

Advertisements

December 29, 2007

The Lambdalator

Filed under: newLISP — newlisper @ 16:34

Not available in the archive version

I’ve added a link to my current experiment – an online interactive Lisp web page – to the list of links on the right. The eventual aim is to get Lisp (newLISP of course) on an iPhone. Have a go!

December 12, 2007

Christmas lunacy

Filed under: newLISP — newlisper @ 15:29

If you’re stuck for gift ideas this christmas, how about printing out a paper version of this 2008 lunar calendar, generated and drawn by a newLISP script with some help from PostScript and PDF?

I spent a few minutes trying to generate this calendar in languages other than English. (That “en” is a clue!) It was easy enough to produce the month and day names in the different languages, using newLISP’s set-locale function:

(set-locale "nl_NL")

; netherlands
(set 'day-of-week
    (date start-date 0 {%A}))

;-> "woensdag"
(set-locale "C")

; quickly back to default locale

But unfortunately I think PostScript isn’t very clever when it comes to Unicode, and it failed to translate the strings properly. It’s not much of a problem for some languages, but it’s more serious for others (and disastrous for Russian):

среда

so until I work out how to get Unicode strings from newLISP to PDF via PostScript, I’m going to stick with English. If you have any clues, please let me know – the internet has let me down, again!

December 6, 2007

Adventures in newbie-newLISPland

Filed under: newLISP — newlisper @ 12:27

I’ve been looking through some of my first attempts at programming in newLISP. One thing I noticed was that at first I had trouble working out how to step through a list and process adjacent elements one pair at a time. Come with me now back to newLISP-newbie land!

To reduce the problem to its simplest case, suppose that we want to work through a list looking at each pair of items:

(set 't (sequence 0 13))

0 and 1
1 and 2
...
12 and 13

Solutions are easy to see now, but for some reason I could think only of using dolist or for, which are the more conventional tools for working through lists.

dolist keeps the current position in the list in a system variable $idx, so you can use that to find the next element, given that the loop variable i is the current element.

(dolist (i t)
    (println { processing } i { and }
        (t (+ $idx 1))))

Here, the implicit addressing (t $idx) returns the same element as i, so the next one is obviously (t (+ $idx 1)).

But there’s a trap for the newbie:

processing 0 and 1
...
processing 12 and 13
processing 13 and 13

Helpfully, newLISP won’t crash your scripts just because you overstepped the end of a list, but it definitely is your job to stop processing the list at the right stage.

So let’s add a break condition:

(dolist (i t (= $idx
            (- (length t) 1)))
    (println { processing } i { and }
        (t (+ $idx 1))))

This now stops the loop when the penultimate item in the list has been processed.

How about for? This can also work:

(for (i 0 (- (length t) 2))
    (println { processing }
        (t i) { and }
        (t (+ i 1))))

It’s easy to make mistakes if you’re not concentrating; there are 14 elements in the list; we use index numbers 0 to 13 to get them; with for loops that means stopping at one less than the length; and as we’re doing pairs we stop two before the length.

But there must be a better way. How about using apply?

(apply
    (fn (a b)
        (println { processing } a { and } b)) t 2)

See that last ‘2’. The anonymous function uses two arguments, and the 2 tells apply to use two arguments at a time. It looks like it works nicely:

processing 0 and 1
...
processing 12 and 13

But the newLISP manual says that the result of each application is re-used as the first argument for the next application. What’s happening is that the result of that println expression was the last number evaluated (which was b), and that was also, conveniently enough, the value that we wanted to use as the first number for the next pair.

To see what’s going on, make the lambda function return something else:

(apply
    (fn (a b)
        (string a { and } b)) t 2)

;->
 "0 and 1 and 2 and 3 and 4 and 5 and 6 and 7 and 8 and 9 and 10 and 11 and 12 and 13"

So I think it’s possible to use apply to apply a function to pairs of items if you remember to return the value of the last member of each pair, so that apply can use it for the next pair.

And you could use map:

(map
    (fn (a b)
        (println a { } b))
    (chop t)
    (rotate t -1))

which uses two versions of the list, chopping the end of one and rotating the second. Helpfully, the extra element in the second list is ignored.

More solutions welcome!

Comment from Lutz

… and here is yet another one:

(set 'theList (sequence 0 13))

(dolist (t (explode theList 2 true))
    (println "processing " (t 0) "and " (t 1)))

the ‘true’ flag in the explode expression makes sure that only full pairs are processed if ‘theList’ has an uneven number of elements.

ps: thanks for putting on the Santa theme again ;-)

Comment from newlisper

So suitable for even-length lists…

(I don’t know why Santa deserted the site for a day… :-)

Comment from talk.do.stop

My version (both for odd and even lists):

;newlisp

(map 
  (fn (x y) (println x " and " y)) 
  (0 -1 theList) 
  (rest theList))

Newsfeeding

Filed under: newLISP — newlisper @ 09:20

Newsfeeding

I’ve been playing with the Atom newsfeed script again. I’m sorry if you’ve noticed it playing up recently.

My newsreader (NetNewsWIre) tries to merge old posts with the contents of the incoming news feed, and I ended up with quite a few duplicated entries. The best way to clear this up is probably to unsubscribe and resubscribe again!

The latest iteration of atom.cgi (available on the downloads page) collects the five most recent posts and the ten most recent comments (I don’t know whether there’s an interface to set this externally?). It displays them mixed and sorted chronologically, and sets the ‘update’ date to the date of the most recent item.

With any luck, this will all work nicely. For a while!

December 2, 2007

Formatting

Filed under: newLISP — newlisper @ 23:55

I decided to have another go at the syntax colouring and code formatting stuff this week. And this time I decided to try and do the job more thoroughly.

The first part of the task is to convert the newLISP source code into a list of elements. So, given some code like this:

(cond
    ((= start end)
        (push (list "white-space" source-string) token-list -1))

the resulting list of lists looks like this:

("left-paren" "(")

("code" "cond")

("left-paren" "(")

("left-paren" "(")

("code" "=")

("code" "start")

("code" "end")

("right-paren" ")")

("left-paren" "(")

("code" "push")

("left-paren" "(")

("code" "list")

("quoted-string" "\"white-space\"")

("code" "source-string")

("right-paren" ")")

("code" "token-list")

("code" "-1")

("right-paren" ")")

("right-paren" ")")

This format is a bit wordy, but it’s readable, and useful for when things go wrong… The module that does the tokenizing – Tokenize – draws on useful code from newLISP guru Fanda.

The second part of the task is to take this list and produce some reasonably-formatted output. This is quite difficult; it’s surprising how many subtle layout ‘rules’ you use. Trying to automate all of these was way too hard, so I quickly decided to think of this utility script as a rough first-draft tidier, rather than a final-draft polisher.

Say, for example, you found this poorly-formatted piece of newLISP lying in the trash:

(define (process_sof marker , len
precision height width components) (set  ' len (read_2_bytes)) ( set 'precision (
read_1_byte)) (set ' height
(read_2_bytes)) (set '
width (read_2_bytes)) (set ' components
(read_1_byte)) (unless (= len (+ 8 (*
components 3)    )  ) 
(throw "process_sof: bogus length"))
(return (list width height))) 

The formatter renders it like this (and adds colours for HTML display):

(define (process_sof marker , len precision height width components)
    (set 'len
        (read_2_bytes))
    (set 'precision
        (read_1_byte))
    (set 'height
        (read_2_bytes))
    (set 'width
        (read_2_bytes))
    (set 'components
        (read_1_byte))
    (unless (= len
            (+ 8 (* components 3)))
        (throw "process_sof: bogus length"))
    (return
        (list width height)))

which is at least more readable, and a good place to start applying your own choice of styling. The rigorous indenting for each new level of parentheses is probably too extreme – you usually want this more for indicating the start of new structures, rather than midway through set expressions, as here.

While we’re outputting the various elements of the source, we can apply any sort of formatting. For HTML, we can apply CSS tags. The advantage of having first produced a list of tokens is that keywords can be processed with more control. For example, we could distinguish between the different types of element – primitives, strings, numbers, arrays – using code like this:

(set 'type-number
    (& 15 (nth 1 (dump
                (eval-string k)))))

(case type-number
    (0 (set 'result
            (list {} code-element-string {})))
    (1 (set 'result
            (list {} code-element-string {})))
    (2 (set 'result
            (list {} code-element-string {})))
    (3 (set 'result
            (list {} code-element-string {}))) ...

It would be easy to modify this to produce different output for all functions that belong to a more general category, such as arithmetic or loop functions.

You could also add some checking and testing routines to the script. For example, the superfluous parenthesis in the following code:

(define (process_sof marker , len precision height width components)
(set 'len
    (read_2_bytes))
(set 'precision
    (read_1_byte))
(set 'height)
    (read_2_bytes)))

produces a question mark:

(define (process_sof marker , len precision height width components)
    (set 'len
        (read_2_bytes))
    (set 'precision
        (read_1_byte))
    (set 'height)
    (read_2_bytes))
)
?

although sadly it doesn’t notice the parenthesis in the wrong place, just that there was one too many by the end. Well, it’s early days yet!

Comment from Lutz

What happened to the beautiful blue ‘Santa Claus’ theme, which was on this site yesterday? I liked that :-)

Comment from cormullion

Still here! :)

December 1, 2007

Problems

Filed under: newLISP — newlisper @ 14:30

Not relevant in the archive version>

Apparently this site doesn’t work properly in Internet Explorer 7.

I think that that’s a Windows-only browser, and therefore hard for me to test unless I go out and bought some Windows hardware and software…

(I believe both Firefox and Safari work on both Macs and Windows, and that Firefox also works on Linux.)

I don’t know what the problem might be. I fixed the few warnings and errors that the W3 Validator flagged (I encoded some stray ampersands, and added DIVs to FORM elements), so it’s possible that it now works.

Also…

I made a small change to the newsfeed script last week, and ever since then I’ve been getting non-stop updates in my RSS newsreader even when nothing has changed. This is another problem that might take some time to fix since I have no idea what the problem is.

I hope that normal service will be resumed as soon as possible.

Comment from newlisper

I found the problem with the news feed. I was using the database change date using file-info as the ‘updated’ time. But the database file changes sometimes even when no comments or posts are added. (I don’t know why that happens)… Luckily that can be fixed easily by looking the most recent addition instead.

Create a free website or blog at WordPress.com.