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

Topics - TedWalther

#21
Sometimes when I am parsing dirty text, there are tabs mixed with spaces, and even other whitespace characters.  So, the "trim" function almost does what I want, but because it is limited to a single character, it doesn't work on such dirty text.



So, I request that in the "trim" section, you add words similar to this:



To trim arbitrary whitespace from the beginning and end of a string, you can do this:



(set 'str "  t  Hello World!t  t")
(replace "^s+|s+$" str "")
=> "Hello World!"


I suggest you add this to the documentation, because as a new user, when I want to "trim" the whitespace from the edges of my strings, the "trim" function is the first place I look.  And I imagine this isn't an uncommon case.  I actually haven't ever needed to use the trim function in its current form.



Or if you added a "regex" version of trim, with a trailing regex options parameter, then I could do



(trim " t foo t " "s" 0) => "foo"
#22
Lutz, I did some tests last week, and it appears (could be wrong) that struct is only supported when libffi support is compiled in.  Is this true?  If so, would it be hard to enable struct even without libffi support?



Also, is libffi a Unix only thing, or is there Windows support as well?
#23
It is true, I can do (apply date-value (now))

However, I have been working with Julian days for a while, and just generally doing date and time related stuff, and so I request that you add the call pattern:



(date-value list)

Ex:
(date-value (now))


This is parallel to how arguments are dealt with in that format function, so it makes sense from a "principle of least surprise" perspective.
#24
This affects dotimes, dolist, and the rest of the family.



I had a situation where I needed to scan through a list of numbers, and find the list index of the number that is just less than my target number.



Example:



(set 'foo '(1 5 10 20 100 105))

(dotimes (i (+ -1 (length foo)) (> (foo i) 50)) (foo i))
=> true
;; was expecting return value of 20 (last value before triggering break condition)


With the break condition, the loop always returns true.  This isn't what I expect; I expect the last value evaluated inside the form, not the condition test.  I want to abort the loop as soon as I find the value I'm looking for.  Is this wrong?  It affects pretty much all the looping constructs, and was very surprising to me.  Without the break condition, the loops return the last value evaluated in the body.



Also, is there a better idiom to do such scanning, some sort of binary search function?



I understand it is useful to know whether the break condition was triggered or not, couldn't that be saved in a system variable $brk the way regex output is?  Also, even leaving $idx behind after a form evaluation would be nice too.
#25
Lutz, could you enable array support in dolist?  I'm using 2.6.0; if this has been changed in later versions, disregard.



Edit:



And yes, I see the array-list function.  Is there a technical reason why it is better to explicitly do an array conversion, rather than iterating over the array directly?
#26
Since format doesn't print numbers as ordinals, (fault of the underlying printf function) I made a function to do it.



This takes a number, and returns a string in ordinal form.



1 becomes 1st

2 becomes 2nd

3 becomes 3rd

4 becomes 4th



And so on.



(define (ordinal n)
  (let (nn (string n))
    (cond
      ((regex {1[123]$} nn) (string nn "th"))
      ((regex {1$} nn) (string nn "st"))
      ((regex {2$} nn) (string nn "nd"))
      ((regex {3$} nn) (string nn "rd"))
      ((regex {[4567890]$} nn) (string nn "th"))
      (true nn))))
(global 'ordinal)


I've put this in my init.lsp.  Handy little function.



Sample usage:



> (ordinal 3)
"3rd"
> (ordinal 4)
"4th"
> (ordinal 65)
"65th"
> (ordinal 10)
"10th"
> (ordinal 11)
"11th"
> (ordinal 12)
"12th"
> (ordinal 13)
"13th"
> (ordinal 14)
"14th"
> (ordinal 24)
"24th"
> (ordinal 23)
"23rd"
> (ordinal 21)
"21st"
#27
I propose this for addition to the Code Snippets or Code Patterns document.



The binomial coefficient shows you how many unique combinations of k objects you can derive from a set containing n objects.



The standard way to calculate the binomial is like this: n!/k!(n-k)!

The implementation looks like this:



(define (binomial-coefficient n k)
  (/ (factorial n) (* (factorial k) (factorial (- n k))))


Implementing that in the straightforward way quickly makes you run out of stack space.  This implementation is 7 times faster:



(define (binomial-coefficient n k)
  (if (> k n)
    0
    (let (r 1L)
      (for (d 1 k)
        (setq r (/ (* r n) d)) (-- n))
      r)))


It is also bignum friendly; you aren't limited by the size of integer, even if you put integers in as arguments; the function auto-converts to bignum for you.



This faster algorithm was translated from C code found here:



    http://blog.plover.com/math/choose.html">http://blog.plover.com/math/choose.html



It is based on algorithm found in "Lilavati", a treatise on arithmetic written about 850 years ago in India. The algorithm also appears in the article on "Algebra" from the first edition of the Encyclopaedia Britannica, published in 1768.
#28
newLISP is being discussed on Eric Raymond's blog as the "batteries included version of LISP".  Eric has said he uses Python because he hasn't found any "batteries included" versions of LISP.  Perhaps some people here may want to head over and add their comments.



http://esr.ibiblio.org/?p=5211#comments">//http://esr.ibiblio.org/?p=5211#comments



Eric Raymond was co-inventor of the term "Open Source", and author of The Art of Unix Programming, and The Hacker's Dictionary.
#29

; walks a disk directory and prints all path-file names
;
(define (show-tree dir)
    (if (directory dir)


I'm pretty sure (directory dir) above is supposed to be (directory? dir)



http://www.newlisp.org/CodePatterns.html#toc-5">http://www.newlisp.org/CodePatterns.html#toc-5



Both versions work, but I think (directory) is more likely to throw an error or fail.
#30
newLISP in the real world / resolution of a float?
October 17, 2012, 02:46:49 PM
I have been converting some JavaScript code to newLISP.  It is detailed astronomical calculations.  Finally I notice something.  The floats in newLISP are only 10 decimal digits long, while those in JavaScript are 16.  I looked into the IEEE standard; there is 52 bits in which to store an integer without any loss of precision.  That matches the output of JavaScript.



Lutz, are we using IEEE 64 bit floats in newLISP by default?  I was hunting some bugs down for hours now, until I noticed this difference in precision.
#31
Whither newLISP? / extract analogous to extend?
February 08, 2012, 10:07:45 PM
I was just trying to use "pop" to pop several items off the front of a list.  I'm making a MIDI debugger.  I've been very happy with the ease that newLISP has allowed for bit-banging this serial protocol.



My only gripe so far is that there is no equivalent to "pop" that lets me take multiple elements from a list.  How about "extract" that is like "slice", but destructive like "extend"?   Or some boolean flag to slice?



That, and bind wants the variables in the association list to all have names that begin with Uppercase.  That is annoying.  I note that the examples in the manual don't require this.  Am I doing something wrong?  Bind+unify is very cool, but the Title-case requirement is a boner-killer.  Otherwise, a syntax like (setq '(a b c d) (some-function)) would be nice.  Similarly with the let family.  Or is this something where I am supposed to use macro wizardry by diving into my copy of Paul Graham's "On Lisp" and translating to newLISP?



Ted
#32
Whither newLISP? / current-char to match current-line?
January 15, 2012, 11:04:15 PM
Can you add in current-char to match the functionality of current-line?  Or else have read-char put the read char into current-line?
#33
I just got confused tonight.  It is handy for the empty list to be a "false" value.  I thought maybe it was only nil that registered as a false value.  But since the empty list is a false value, how about the empty string, and the number 0?  Lutz, did you already post on your reasons for this design decision?
#34
newLISP and the O.S. / Wierd permissions bug
August 20, 2011, 01:46:02 PM
I have a directory with the permissions r-x------, owned by myself.  I also have some directories that are owned by root.



I have a script that I am running to find duplicate files on my harddrive.  Over the years a lot of stuff has been duplicated, cruft has accumulated.



When my script hits the directories owned by root, it crashes.  So I run the script with "sudo".  Or I log in as root using "su".  This fixes the problem.  But then we get to my special directory with the permissions r-x------.  (directory ".myspecialdir") doesn't yield ().  It gives "nil".  When I run the script as myself, (directory) gives () as expected.
#35
I have made a module called "getopts".  It doesn't use its own context.  I don't think it needs to.  If people can try it out, it does the following:



It parses command line options in the following forms:



-f filename
-ffilename (-f filename)
-avh (-a -v -h)
-avfboo (-a -v -f boo)
--long-option
--long-option with-argument
--long-option=with-argument (--long-option "with-argument")
-- (everything after -- is ignored)


Anything that is not an option, or an argument to an option, is just accumulated to a list.  At the end of the option processing, this accumulated list is returned for your own custom processing.



There is just one possible glitch.  I start the argument parsing at index position 2 of main-args.  For my scripts, this works well.



As a bonus, the way it is set up, the "usage" function, automatically lists all the options that you have specified.  Also, unlike in C, you don't call getopt repeatedly.  The getopts function does it all in one pass.  Here is an example of how to use it:



(module "getopts.lsp")

(short-opt "v" (++ verbosity) nil "Increase verbosity")
(short-opt "q" (setq verbosity 0) nil "Quiet")
(short-opt "?" (usage) nil "Print this usage message")
(short-opt "h" (usage) nil "Print this usage message")
(short-opt "o" (setq output-file arg) "file" "Output file")
(long-opt "help" (usage) nil "Print this usage message")
(long-opt "quiet" (setq verbosity 0) nil "Quiet")
(long-opt "verbose" (++ verbosity) nil)
(long-opt "output" (setq output-file arg) "file" "Output file")

(println (getopts)) ; this shows the command line datum that weren't options
(println "Verbosity: " verbosity)
(println "Output To: " output-file)
(exit)


Example usage:



$ ./test.lsp --output foo -obar -v --quiet -vv arg1 arg2
("arg1" "arg2")
Verbosity: 2
Output To: bar


There is just one issue.  If I pass an argument to newlisp, it changes the starting point for processing in main-args.  I see no way to detect this.



#!/usr/bin/newlisp

$ ./test.lsp foo bar
main-args: "/usr/bin/newlisp" "./test.lsp" "foo" "bar"

#!/usr/bin/newlisp -m 50 -s 1024

$ ./test.lsp foo bar
main-args: "/usr/bin/newlisp" "-m 50 -s 1024" "./test.lsp" "foo" "bar"


See how it differs?  Wouldn't it be better if there was an empty string there always, in index position 1, if there are no arguments passed to the newlisp interpreter?
#36
Whither newLISP? / Are contexts heavyweight?
April 23, 2011, 12:17:41 PM
I was meditating on how to represent JSON in newLISP, in a way that would easily let me convert it back into JSON.  And it occured to me that anonymous contexts would make the task easy.



Lutz, are you opposed to anonymous contexts because contexts are quite heavy-weight, and you want us to only use them when necessary instead of using them as the hammer for all nails?  And because it would be a lot of work to work them into the ORO framework?



So, that is two possible reasons:



* Making anonymous contexts work with ORO would be tough

* Contexts in general are heavyweight, moreso then a let scope?



Am I understanding it right?
#37
mul and div do what I expect when used as unary operators.



(div 10) => 0.1 (10 becomes 1/10)

(mul 10) => 10 (10 becomes 10*1)



But mod... mod does nothing.



Could mod be made so it behaves the following way?



(mod 10) => 0 (10 becomes 10%1)

(mod 10.5) => 0.5



This would let mod act as the builtin "frac" for getting the fractional part of a number; right now we have round, floor, and ciel that already give us the integer part of a number.  And yes, I can do (mod %number% 1).  But in keeping with the unariness of the other operators, I request this change.



Then I could do (constant (global 'frac) mod) in my .init.lsp



Ted
#38
Whither newLISP? / anonymous rb-trees?
October 21, 2010, 12:17:40 PM
You create an array with (array ...) but it mostly acts like a list.



I've often wanted anonymous rb-trees.



Often, I'd like to have a list of "objects", but want to access the data in them with the same syntax as with rb trees.  It is nice that we now have anonymous objects;  can we have anonymous rb-trees?



Also, I'm still trying to wrap my head around the way that contexts and rb-trees are crumpled together.  They seem like unique and independant contexts.



Lutz, would it be possible to separate them out?  When I use rb trees, I don't usually need the other stuff that a context implies.  Not saying there is any overhead speedwise. It is just grappling with it in my head.



A lot of times I deal with data where I need to stash it in rows, and there is a lot of self-similarity, but there is also odd data that pops in which I also want to stuff into the data structure and save.



How about (rbtree ...) ?



This would fit in with the default functor; right now there is no way to access the "default functor" other than with (define), but with an rbtree, the default function could be used without generating a context.

Ted
#39
Whither newLISP? / 64 bit dates
October 17, 2010, 07:43:32 PM
Most platforms have updated the Unix date functions to be 64 bit, so they can handle dates before 1970 and after 2032.  Can the newlisp implementation detect this on the fly and use it where possible?
#40
In newlisp, I notice that the prompt doesn't always reappear after I press Enter.  I have to press enter a second time.  Try it; start up newlisp, and hit enter at the prompt.



Now, if I type (println)[enter], the prompt comes back right away.