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

#31
Whither newLISP? / Re: magic numbers
January 22, 2013, 04:32:05 PM
Thanks for the list of places to cover, Lutz.



Adding adhoc constants to individual scripts will lead to an inevitable mess of misspellings. The idea of a company-wide constants module is good -- and such a project would be the beginnings of a globally used Constants.lsp or English.lsp or SomeSuch.lsp, allowing so inclined devs to 'turn on English constants' a la Perl.
#32
Whither newLISP? / Re: magic numbers
January 21, 2013, 07:10:06 PM
Good to know, Lutz, thanks.



So... care to weigh in on the magic-number side?

This phenomenon exists in several places throughout the newLISP API. Many functions take an optional integer parameter that is an OR compositie of individual option values. As bare numbers, this makes reading code quite difficult. Perl (and awk before/after it) went through these criticisms and came out with the English package for tree hugging hippies like myself. Am I the only one here who feels this might benefit the newLISP landscape?
#33
Whither newLISP? / Re: magic numbers
January 21, 2013, 01:55:44 PM
Thanks for playing along, Cormulion.



Your solution is certainly the easiest of the named-symbols implementations. On the down side, it produces fairly verbose symbols.



Another question I had about the code: two fours?



Is it possible for the state of (last-error) to change between testing for Error:problem-accessing-file and the (println ...) reporting it? If not, the code can be simplified to:


(error-event (fn ()
    (if (= Error:problem-accessing-file ((last-error) 0))
        (println "The error was: " (last (last-error)))
        (println ((last-error) 1)))))


no?
#34
Whither newLISP? / magic numbers
January 20, 2013, 03:18:58 PM

(error-event (fn ()
    (if (= 4 ((last-error) 0))
        (println "ERR:" (last (last-error 4)))
        (println ((last-error) 1)))))
[/quote]

For a while now I have been unconsciously squirming in my seat when reading over code like this. This morning I became aware of that discomfort and cried in alarm: magic numbers!



To the trained webber this might read transparently lucid; succinct even. But to the novice seeing this for the first time or the junior revisiting six month (week? day?!) old code, these opaque little numbers muddy the cognitive stream, making it nearly impossible to reason about the code until the manual has been consulted.



, where ((last-error) 0) and ((last-error) 1) retrieve the number-only and string-only, respectively.



Ok. That's not too bad. Two things to learn there and you're set for life:

1. newLISP's awesome implicit list indexing;

2. (last-error) returns such an ordered pair



fine, but what about those 4's...?


(if (= 4 ((last-error) 0))

Is now approachable: If the last error number is 4...

But, what is error 4?

Another quick test:


(last-error 4)

yielded:


(4 "problem accessing file")

ah... light-bulb



While the solution to the mystical zero and one numbers was trivial, the same approach will not work here -- it is not plausible to memorise the table of errors.



Error Codes[/url] handy;



2. Have constants representing error numbers:


(last-error ERR_FILE_ACCESS)
or the more cryptic:
(last-error EFACC)

Note: I am not literally suggesting either actual constant here -- I presume actual thought would be given to such a scheme.



[size=120]tl;dr[/size]



What is the recommended way to reduce magic numbers in our newLISP code?
#35
newLISP in the real world / Re: Send byte array via TCP
January 19, 2013, 05:28:25 AM
I have never done net coding, but I thought that was exactly what the (pack ...), (unpack ...) pair were for - to be able to send binary values encoded as strings to be decoded back into their proper forms at the other end. No?
#36
newLISP in the real world / Re: Send byte array via TCP
January 19, 2013, 04:10:15 AM
I'm going to guess here, csfreebird, that you can use the (pack ...) and (unpack ...) functions for this. See the newLISP User Manual for these functions. From a quick look, it would seem you'd use:


(pack ">d" your_short)

For a signed big-endian short.



Heh... and on clicking Submit, it seems that Cormullion agrees. :)
#37
There is the


/usr/lib/i386-linux-gnu/libsqlite3.so.0

analogue too...   :-/



This bit me yesterday when I was testing jazper's sqlite3 stuff. I whimped out and created a symlink from /usr/local/lib/libsqlite3.so, but that really was just a kludge.
#38
newLISP in the real world / Re: cgi again
January 16, 2013, 08:58:45 PM
o_O what am I gonna do with all this popcorn?!



Thanks, RickyBoy & Cormullion - it was the case sensitivity issues I was unsure about. I was fairly sure that the NULL was necessary - it seemed so in standalone tests of sqlite3.lsp. I don't think I made any other changes, jazper, apart from the aesthetic (load ...) -> (module "...").



FWIW, I tested sqlite3.lsp in the console and a standalone script before introducing the cgi layer. Primarily I did this because I always like to limit the number of variables when testing/fixing something, but a very real secondary in this case was my utter lack of cgi experience.



Mmm... popcorn...
#39
newLISP in the real world / Re: cgi again
January 16, 2013, 05:34:24 AM
Try:


#!/usr/bin/newlisp
;;; to create table, used this -- CREATE TABLE UsrTbl(Id INTEGER PRIMARY KEY, UserName TEXT, UserEmail TEXT)

(print "Content-type: text/htmln")
(module "cgi.lsp")
(module "sqlite3.lsp")

(println
 [text]
 <br>
 <form action="UPDTDB2.cgi" method="POST">
 <pre>
 User name:<input type="text" name="UserName"><br>
 Email    :<input type="text" name="UserEmail"><br>
 <input type="submit" value="Go">
 </pre>
 </form>
 <br>
 [/text])

(define (rslt sql-text)
 (set 'sqlarray (sql3:sql sql-text))    ; results of query
 (if sqlarray
  (map println sqlarray)
  (println (sql3:error) " query problem ")))

(define (insrt sql-text)
 (set 'qry (sql3:sql sql-text))
 (if qry
  (println "ok")
  (println (sql3:error))))

(set 'database "JCDB.db")
(sql3:open database)

(println {<br>})
  (set 'name (CGI:get "UserName"))
  (set 'email (CGI:get "UserEmail"))
  (set 'sqlstr (string "INSERT INTO UsrTbl VALUES(NULL,'" name "','" email "');" ))
(insrt sqlstr)

(println {<br>Hit the [back] button on your browser to got back<br>})

(exit)

  ;;; eof ;;


I am not familiar enough with either newLISP or cgi to claim which of the small changes I made were absolutely necessary versus the ones which merely felt right stylistically. No doubt Cormullion or RickyBoy will be along soon to show us what real style looks like. :-) I for one will have my popcorn ready for that too.
#40
newLISP in the real world / Re: list all in directory
January 14, 2013, 12:13:40 AM
Use the (copy ) function on the string.


(replace "hello" (copy x) "goodbye")
#41
newLISP in the real world / Re: list all in directory
January 13, 2013, 11:48:18 PM
This is shown in http://www.newlisp.org/downloads/CodePatterns.html">CodePatterns under Walking A Directory Tree in section 5.
#42
newLISP in the real world / Re: Searching in lists
January 08, 2013, 11:45:48 PM
Without seeing your data, I can only guess at the structure. As such, this code will almost certainly fail:


(map rest (ref-all '("title" *) x match true))

Hopefully the intent survives though and you're able to find a built-in search function to suit your needs. There are about three hundred of them by my last count, once you factor in the myriad switches and leavers and moon phases that affect their operation.



Ok... it is perhaps a bit persnickety of me to blame my tools for my own inability to learn/memorise the many different search functions in newLISP. I need to find a way to better absorb and retain this knowledge. :-/
#43
It is the wise man who chooses another direction when he sees he's on the wrong path. Well played, rickyboy. Intellectually, I get why the macro form is not playing nice for us, but I lack the necessary coalface time at the keyboard to properly internalise that lesson. This is an area of my lisp that will take much practice. Trying to learn macros before knowing lisp in the first place is... hard (read: foolish :-/ ).



To your new solution: nice. I hadn't given any thoughts to type checking and consistency. Good to learn.



Again, thanks for your tutelage. Keep the ninja suit handy; you look good in black. :-)
#44
Ah... a snag I hit in the macro forms, rickyboy, is the resulting order of execution when called on a nested call of itself:


(define (get_workspace_trees , x)
  (let (x '())
  (dolist (output (get_active_output_names))
    (push (list output (nodes "content" (nodes output (get_tree)))) x))
  x))


The code for the "content" block executes before the `output` block. Am I doing it wrong? Where to from here? o_O
#45
Wow. That's brilliant, rickyboy! Thanks for taking the time to show and explain those ideas to me. That is exactly what I was looking for (but didn't know what it would look like) when I asked for places to improve my code. I am new to lisp, so knowing when to reach for a macro is still beyond my reach at this stage. I will study your code... after work today... and see if I can't +1 my macro-fu.



Some off the cuff observations before I do:



I like the look of the 'clean' (ref...) inside the macro form.

I don't mind splitting that onto its own line; it does aid readability.

I don't think I've tried (lookup...) so, more exploration needed there.

The macro generating macro is going to take me a while to pick apart. Awesome. :-D