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 - Astrobe

#16
I used (net-receive-from) to make a little UDP proxy under linux. When I ran it under windows, it unexpectedly didn't work.



It seems that under Windows (XP), the address field which is returned is in the form ip-address:port.
#17
Maybe a useful tip: use letex to avoid fiddling manually with self-fields. For instance:



(letex (H '(self 1) L '(self 2))
   (define (rectangle:perimeter) (* 2 (+ H L)))
   (define (rectangle:area) (* H L)))
#18
Whither newLISP? / Re: fexpr issues
March 05, 2014, 09:26:00 AM
I know this is different from what I initially asked for, but...



if you remove lines from 4912 to 4921 (the ones that insert the expansion code), one gets interesting options for forging the replacement expression.

Like for instance this improved curry:



(macro (curry*)
  (case (length $args)
    (2 (letex (F (args 0) A (args 1)) (fn(x) (F A x))))
    (3 (letex (F (args 0) A (args 1) B (args 2)) (fn(x) (F A B x))))))

(set 'K (curry* + 1))
> (lambda (x) (+ 1 x))
(set 'L (curry* + 1 2))
>(lambda (x) (+ 1 2 x))


(copied by hand from another screen; parens might be missing)



What I'm thinking is the functionality of "macro" already exists in a module, and the term "macro" can be confusing together with define-macro, so... What if we call our new feature "inline" (for instance), and we don't restrict it to the functionality of its ancestor?
#19
Whither newLISP? / Re: fexpr issues
March 05, 2014, 03:54:00 AM
Also, I spotted by chance a misuse of define-macro in the "apply" entry: my-gcd is defined as a macro; but if you try (my-gcd 12 18 (+ 1 2 3)) one gets an error.
#20
Whither newLISP? / Re: fexpr issues
March 04, 2014, 09:40:35 AM
Oh, nice!



Do I have to wait 10.5.8 to officially come out or can I grab it right now?
#21
newLISP in the real world / read-line optimisation
March 04, 2014, 12:42:09 AM
Hello,



While programming a little tool that analyses some log file, I've noticed that read-line is a bit slower than one would expect. Looking at its code, it appeared to me reading the stream char-by-char could be the cause. I Modified it to use fgets instead:



char * readStreamLine(STREAM * stream, FILE * inStream)
{
char buf[MAX_STRING];
size_t l;

openStrStream(stream, MAX_STRING, 1);

if(fgets(buf, MAX_STRING, inStream)!=NULL)
{
l=strlen(buf);
if(buf[l-1]==0x0A)
        {
             buf[--l]=0;
             if(buf[l-1]==0x0D) buf[--l]=0;
        }
writeStreamStr(stream, buf, l);
return(stream->buffer);
}
else
{
if(feof(inStream)) clearerr(inStream);
return NULL;
}
}


(this hasn't been heavily tested)



However, it doesn't strictly respects the original semantics of read-line with regards to newline characters. To be honest, I don't understand why they are that way, in particular why there is a requirement that a newline at the end of the file has to be erased.



Also, the part about the TRU64 is missing. I don't know if fgets handles EINTR correctly by itself on this platform. I've worked with systems plagued with a similar illness before, and unfortunately the FILE library (which was not standard IIRC) didn't handle very it well.



On the performance side, timings drop from 250ms to 50ms.
#22
Whither newLISP? / Re: fexpr issues
February 28, 2014, 11:07:25 AM
Quote May be if you replace (println k) with (println "=====>" k), you can better follow the debug behavior


Indeed I thought about this possibilty and did something like that. It seems I didn't put enough dashes in my println.


Quotefexprs are functions, so I would argue: the behavior is expected. args should always work in the context of the currently executing function and nested functions/fexprs should all keep their local versions of args, this makes code more readable too.


The problem I see is that one can easily forget that some definition is actually a macro and pass it an expression that contains (args) or $args. This situation typically happens when one nests macros, id est when one uses macros inside macros.


QuoteEven when implemented natively, for every functor expression symbol parsed, you would have to do the lookup, if a reader-event is defined.


What about doing it like Forth? Macro symbols could have a special mark, that triggers their execution (after the arguments have been parsed) at compile-time.
#23
Whither newLISP? / fexpr issues
February 28, 2014, 01:42:33 AM
Consider this dumbed-down version of do-until:



(module "macro.lsp")
(define-macro (DO-UNTIL test B)
 (do-while (not (eval test)) (eval B)))

(macro (DO-UNTIL* T B)
(do-while (not T) B))


(println "test 1")
(define (foo k)
  (DO-UNTIL (<= k 0) (begin (println k) (dec k))))
(foo 3)

(println "test 2")
(define (foo* k)
(DO-UNTIL* (<= k 0) (begin (println k) (dec k))))
(foo* 3)

(println "test 3")
(define (bar*)
  (let (k 0)
(DO-UNTIL* (>= k (args 0)) (begin (println k) (inc k)))))
(bar* 3)

(println "test 4")
(define (bar)
  (let (k 0)
(DO-UNTIL (>= k (args 0)) (begin (println k) (inc k)))))
(bar 3)


First problem: foo doesn't behave correctly under debug; doing (debug (foo 3)) doesn't do the same as (foo 3)



Second problem: bar doesn't work at all, because (args 0) is evaluated in the context fo the macro DO-UNTIL.



Those kind of problems makes it really tricky to use fexprs. On the other hand, rewrite macros provided by macro.lsp don't have these problems, and are also faster because the substitution is done at compile-time. They however increase the code size, but this can be mitigated by factoring out the "big parts" of macros in external functions.



macro.lsp notes that it increases the load-time of scripts. Is the impact significant? What about native and improved support for rewrite macros?
#24
Thanks.



(set 'GA "gappw32.dll")
(struct 'Rect "int" "int" "int" "int")
(import GA "app_new_app" "void*" "int" "void*")
(import GA "app_new_window" "void*" "void*" "Rect" "char*" "long")
(import GA "app_main_loop" "void" "void*")
(import GA "app_show_window" "void" "void*")
(import GA "app_new_label" "void*" "void*" "Rect" "char*" "int")
(import GA "app_new_button" "void*" "void*" "Rect" "char*" "void*")

(set 'GH (app_new_app 0 ""))
(set 'W (app_new_window GH (pack Rect 100 100 200 50) "Thanks Lutz" 0x3F0))
(define (sayHi) (println "Hi!"))
(set 'cb (callback 'sayHi "void*" "void*"))
(app_new_button W (pack Rect 5 5 190 40) "It works awsomely" cb)
(app_show_window W)
(app_main_loop GH)
#25
I'd like to use this nice little GUI library: http://enchantia.com/software/graphapp/">http://enchantia.com/software/graphapp/



The widget set is not as full featured as other libraries but it's good enough for simple user interfaces. Plus it fits in a single 700K DLL and is portable.



The problem is that it passes and returns one of its major structures (Rect) as value: http://enchantia.com/software/graphapp/doc/manual/rect.htm">http://enchantia.com/software/graphapp/ ... l/rect.htm">http://enchantia.com/software/graphapp/doc/manual/rect.htm



Is there, by any chance, some trick to make it work with NewLisp's FFI without writing wrappers?
#26
This Jeff Read on the thread gives us a hard time. Unfortunately, it's not the right place for a discussion about newLisp.



It seems to me he makes some valid points, but what he misses is that it's all about compromises. Yes, ORO and other features of newLisp bring some limitations, but also carry some advantages like extraordinary small footprint (on par with Lua, except that Lua without extensions is almost useless because it is meant to be an embedded language), and fast execution (for a tree-walking interpreter, a technique that usually loses to bytcode interpreters).
#27
This is a property named stability (https://en.wikipedia.org/wiki/Sorting_algorithm#Stability">https://en.wikipedia.org/wiki/Sorting_a ... #Stability">https://en.wikipedia.org/wiki/Sorting_algorithm#Stability), which depends on the sorting algorithm.
#28
newLISP Graphics & Sound / Re: HTML Tag functions?
December 20, 2013, 07:30:44 AM
I started to do something along these lines. The technique is similar to the one used by xytroxon, except the tags generate a tree of strings. Then a "render" procedure walks the tree and spit it out. I don't have the code because it's on my PC atm.



For tag attributes, after various attempts, I came up with a macro named "with:", which sets a global variable to be inserted by the "tag" procedure that implements the tags. Most tags are basically like (define (html) (tag "html" (args)). (set 'html (curry "html")) would have been cool here, but it doesn't work there because the rest of the arguments are the body, and curry only works on 2-arguments procedures.



So the code for a page writes:
(html (body
(with: "type=submit" (form "etc."))))

The drawback is that the order is reversed compared to regular html.The advantage is that one deosn't have 'noise'  parameters. "with:" has to be a macro because newlisp evaluates the arguments first, and the global is not set a the right time.
#29
Ok my bad.
#30
Quote from: "Lutz"The F in FOOP



 When you do:

> (new Class 'Person)
Person
> (Person "JohnDoe")
(Person "JohnDoe")
>


The statement (Person "JohnDoe") returns the same as an object. The object is the functional statement to create itself. The constructor functor Person is also the class id.


I'm sorry but it makes little sense to me. (Person "JohnDoe") is technically an expression, not a statement. It is indeed functional in the sense that it is a pure function, but so is (fn (x y) (+ x y)). The fact that Person is both in the result and is a class id is a neat generalisation of type tags that dynamic languages usually use internally. Calling statements or expressions "functional" doesn't make the language more functional.



If you talk to functional people, they'll tell you that the two main ideas of functional programming are immutability and side-effects management. When I removed (self), I overlooked the fact that (self) allowed to mutate the object, something that I cannot do any more because now the 'methods' receive a copy of the original object. To make it usable again, the method must return a new object:

(define (Person:rename p nn) (setf (p 1) nn) (p))

And that's exactly what a functional program does. Of course it has the downside of creating objects, but that's all the story about functional programming: mutability is a shortcut that saves memory and CPU cycles, but it can become a drawback (for debugging, for the gc, in the presence of threads, etc). If you observe functional programming languages, many features are there in order to deal with the lack of mutability.



Now if we talk about the OOP part, the first thing one could note is the lack of direct support for inheritance. As far as I understand it, (def-new) and (context)'s second syntax is supposed to help with that. The idea of inheritance is that the derived class "understands" the messages defined in its base class even though it doesn't define them explicitly.

What if we do:

(new Class 'Person)

(Person "JohnDoe")

> (Person "JohnDoe")

(new SubClass 'Person 'Worker)

(Worker "JaneDoe")

>((Person Worker) "JaneDoe")



The newlisp engine could loop over the list in the first item until it finds the desired method symbol in the context.