Author Topic: Lisp in Basic  (Read 208201 times)

0 Members and 3 Guests are viewing this topic.

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #840 on: September 25, 2014, 03:34:11 PM »
Hi Rob,

In Russian, LISP is masculine while Scheme is feminine and perhaps that's why I've chosen the latter (quite subconsciously, hehe) for my exercises. And don't get so upset about that marginal message; there are so many people around who really don't know what they're either saying or doing regardless of being in business for only 3 or already 30 years.


Now guys I need your advice. After so many efforts put into LISP-in-BASIC and when its O2 exe size is well on the wrong side of 100KB but still lacking a lot of essential features, I came across a Scheme implementation I called nanoscheme that does much, much more than the current OxyLISP, is 3 times faster than tinyscheme (see the attached benchmark of doubly recursive fibo(35)), has a 5 times smaller executable than OxyLISP to say nothing of tinyscheme, has a clearly defined source code structure, is easy to port to BASIC, and is easily expandable to a full numeric tower and nearly all of R5RS standard even though it doesn't fully support R4RS in its present state.

I want to give up LISP-in-BASIC right away as I see no more reason to maintain it; it's a complete mess as compared to nanoscheme. It simply doesn't deserve any more of our time. It's been a nice toy to get in line with the ABC's of LISP but it's becoming more of a burden than a pleasure to work with.

Would you mind waiting for another week till I get nanoscheme up and running in OxygenBasic?

.

JRS

  • Guest
Re: Lisp in Basic
« Reply #841 on: September 25, 2014, 06:22:24 PM »
Q. What is the best Lisp language to use?

Lisp Programmer:  I don't know. Everything I've tried so far isn't it.  :o

For the SB project TinyScheme works out great as a BASIC Scheme Lisp extension, It's supported and extensible at the C level to add core functionality. Speed isn't my primary objective with the SB TS ext.

@Mike - Before you abandon the LISP-in-BASIC project, does your updated SBLisp version work?
« Last Edit: September 25, 2014, 09:31:59 PM by John »

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #842 on: September 25, 2014, 08:16:39 PM »
Who said I was updating the SBLisp version all this time? I thought I was working with OxyLISP, judging by my screenshots on the forum... :o

JRS

  • Guest
Re: Lisp in Basic
« Reply #843 on: September 25, 2014, 09:25:55 PM »
If you can send me the code where you left off and I might be able to add some of your improvements to the current posted code base on Bitbucket.

« Last Edit: September 25, 2014, 10:18:52 PM by John »

JRS

  • Guest
Re: Lisp in Basic
« Reply #844 on: September 25, 2014, 09:56:33 PM »
I wonder if we can progress on to using Graphics with Scheme/Lisp? What is the standard that most Lisp languages use as a graphics engine and what primitives are supported?

Here is the Script BASIC Mandelbrot example we have used in the past with multiple languages. I would like to see a Lisp example of this.

Code: Text
  1. ' ScriptBasic GFX - Mandelbrot
  2.  
  3. IMPORT gfx.inc
  4.  
  5. s = gfx::Window(640,480,"Script BASIC SDL_gfx Mandelbrot")
  6. ts = gfx::Time()
  7. FOR y = 0 TO 479
  8.   FOR x = 0 TO 639
  9.     cx = (x - 320) / 120
  10.     cy = (y - 240) / 120
  11.     rit = gfx::Mandelbrot(cx, cy, 510)
  12.     gfx::PixelRGBA s, x, y, rit * 32, rit * 16, rit * 8, 255
  13.   NEXT
  14. NEXT
  15. te = gfx::Time()
  16. gfx::stringColor s, 20, 15, "Time: " & FORMAT("%.4f",(te-ts)/1000) & " Seconds." & CHR(0), 0x000000ff
  17. gfx::Update
  18. WHILE gfx::KeyName(1) <> "+escape"
  19. WEND
  20. gfx::Close
  21.  



 

.

Charles Pegge

  • Guest
Re: Lisp in Basic
« Reply #845 on: September 26, 2014, 12:01:18 AM »
Hi Mike,

Roughly how many core operators are there in NanoScheme?

I am sure there will be several opportunities to reduce the binary size and timings, but that is phase 2 :)

RobbeK

  • Guest
Re: Lisp in Basic
« Reply #846 on: September 26, 2014, 12:11:59 AM »
Hi,

John : as for the graphics, BigLoo , STALIN and GCL come with Japi (and IIRC it is also used with Haskell ).
GCL uses probably an early version, some parts are missing (progress bar - incomplete textarea ...) , STALIN uses a modest subset however because the set up is done by an ini file it can be updated (which is not possible with GCL)  -- I have written the Japi bindings for NewLISP ,CLisp and Closure Lisp.  But most CL's use Tk nowadays ...  http://www.peter-herth.de/ltk/

Mike, where did you download nanoScheme ??  -- the link I found gives a erroneous distribution -- it will not install (windows registery key error --   it tries to do nanAscheme  >:(    Maybe you found it on a Russian site ???
In my native language both Lisp and Scheme are masculin  (but a scheme is neuter )   and like in German a language in general is feminine  -- it's the old language from Brabant , not Dutch -- we use the articles like in German  (der , die , das ) - while Dutch has two (mas/fem the same and neuter ) and English has only one.
The nice thing is, that I can conversate with my friend in Aachen in about the same dialect ..  it is still probably related with the empire of Carolus Magnus (must be strange , because I can not hear any difference between someone from Sankt-Peterburg and Vladivostok ...   )

best Rob



JRS

  • Guest
Re: Lisp in Basic
« Reply #847 on: September 26, 2014, 12:38:12 AM »
Rob,

I'm thinking about adding a extension to TS that would call Script BASIC functions and subs passing arguments back and forth.  8)


Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #848 on: September 26, 2014, 05:44:12 AM »
Hi,

Some more info on nanoscheme. It compiles perfectly without a single modification to its code by FBSL's DynC but: i) its footprint (48KB) turns out roughly twice larger than 23.5KB when compiled with gcc -Os (optimize for small size); and ii) its speed in DynC is twice slower than when compiled with gcc -Os, but still 50% faster than that of tinyscheme.

And here is nanoscheme's initialization file that will give you some idea what the language is capable of syntactically at its current state:

Code: [Select]
; nanoscheme initialization file

(define (caar x) (car (car x)))
(define (cadr x) (car (cdr x)))
(define (cdar x) (cdr (car x)))
(define (cddr x) (cdr (cdr x)))
(define (caaar x) (car (car (car x))))
(define (caadr x) (car (car (cdr x))))
(define (cadar x) (car (cdr (car x))))
(define (caddr x) (car (cdr (cdr x))))
(define (cdaar x) (cdr (car (car x))))
(define (cdadr x) (cdr (car (cdr x))))
(define (cddar x) (cdr (cdr (car x))))
(define (cdddr x) (cdr (cdr (cdr x))))
(define (caaaar x) (car (car (car (car x)))))
(define (caaadr x) (car (car (car (cdr x)))))
(define (caadar x) (car (car (cdr (car x)))))
(define (caaddr x) (car (car (cdr (cdr x)))))
(define (cadaar x) (car (cdr (car (car x)))))
(define (cadadr x) (car (cdr (car (cdr x)))))
(define (caddar x) (car (cdr (cdr (car x)))))
(define (cadddr x) (car (cdr (cdr (cdr x)))))
(define (cdaaar x) (cdr (car (car (car x)))))
(define (cdaadr x) (cdr (car (car (cdr x)))))
(define (cdadar x) (cdr (car (cdr (car x)))))
(define (cdaddr x) (cdr (car (cdr (cdr x)))))
(define (cddaar x) (cdr (cdr (car (car x)))))
(define (cddadr x) (cdr (cdr (car (cdr x)))))
(define (cdddar x) (cdr (cdr (cdr (car x)))))
(define (cddddr x) (cdr (cdr (cdr (cdr x)))))

(define call/cc call-with-current-continuation)

(define (list . x) x)

(define (map proc list)
    (if (pair? list)
        (cons (proc (car list)) (map proc (cdr list)))))

(define (for-each proc list)
    (if (pair? list)
        (begin (proc (car list)) (for-each proc (cdr list)))
        #t ))

(define (list-tail x k)
    (if (zero? k)
        x
        (list-tail (cdr x) (- k 1))))

(define (list-ref x k)
    (car (list-tail x k)))

(define (last-pair x)
    (if (pair? (cdr x))
        (last-pair (cdr x))
        x))

(define (head stream) (car stream))

(define (tail stream) (force (cdr stream)))

;; The following quasiquote macro is due to Eric S. Tiedemann.
;;   Copyright 1988 by Eric S. Tiedemann; all rights reserved.

(macro
 quasiquote
 (lambda (l)
   (define (mcons f l r)
     (if (and (pair? r)
              (eq? (car r) 'quote)
              (eq? (car (cdr r)) (cdr f))
              (pair? l)
              (eq? (car l) 'quote)
              (eq? (car (cdr l)) (car f)))
         (list 'quote f)
         (list 'cons l r)))
   (define (mappend f l r)
     (if (or (null? (cdr f))
             (and (pair? r)
                  (eq? (car r) 'quote)
                  (eq? (car (cdr r)) '())))
         l
         (list 'append l r)))
   (define (foo level form)
     (cond ((not (pair? form)) (list 'quote form))
           ((eq? 'quasiquote (car form))
            (mcons form ''quasiquote (foo (+ level 1) (cdr form))))
           (#t (if (zero? level)
                   (cond ((eq? (car form) 'unquote) (car (cdr form)))
                         ((eq? (car form) 'unquote-splicing)
                          (error "Unquote-splicing wasn't in a list:"
                                 form))
                         ((and (pair? (car form))
                               (eq? (car (car form)) 'unquote-splicing))
                          (mappend form (car (cdr (car form)))
                                   (foo level (cdr form))))
                         (#t (mcons form (foo level (car form))
                                         (foo level (cdr form)))))
                   (cond ((eq? (car form) 'unquote)
                          (mcons form ''unquote (foo (- level 1)
                                                     (cdr form))))
                         ((eq? (car form) 'unquote-splicing)
                          (mcons form ''unquote-splicing
                                      (foo (- level 1) (cdr form))))
                         (#t (mcons form (foo level (car form))
                                         (foo level (cdr form)))))))))
   (foo 0 (car (cdr l)))))

;; atom?
(define (atom? x)
  (not (pair? x)))

;; memq
(define (memq obj lst)
  (cond
    ((null? lst) #f)
    ((eq? obj (car lst)) lst)
    (else (memq obj (cdr lst)))))

;;    equal?
(define (equal? x y)
  (if (pair? x)
    (and (pair? y)
         (equal? (car x) (car y))
         (equal? (cdr x) (cdr y)))
    (and (not (pair? y))
         (eqv? x y))))


;; (do ((var init inc) ...) (endtest result ...) body ...)
;;
(macro do
  (lambda (do-macro)
    (apply (lambda (do vars endtest . body)
             (let ((do-loop (gensym)))
               `(letrec ((,do-loop
                           (lambda ,(map (lambda (x)
                                           (if (pair? x) (car x) x))
                                      `,vars)
                             (if ,(car endtest)
                               (begin ,@(cdr endtest))
                               (begin
                                 ,@body
                                 (,do-loop
                                   ,@(map (lambda (x)
                                            (cond
                                              ((not (pair? x)) x)
                                              ((< (length x) 3) (car x))
                                              (else (car (cdr (cdr x))))))
                                       `,vars)))))))
                  (,do-loop
                    ,@(map (lambda (x)
                             (if (and (pair? x) (cdr x))
                               (car (cdr x))
                               nil))
                        `,vars)))))
      do-macro)))

.
« Last Edit: September 26, 2014, 06:09:18 AM by Mike Lobanovsky »

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #849 on: September 26, 2014, 06:03:15 AM »
Hi John,

Gotcha again. :)

My idea is that I hereby stop developing LISP-in-BASIC's variant of OxyBASIC because it's a dead end by original design and feature completeness, and I will not release its sources in order to keep our environment tidy. Instead, I suggest rebranding OxyLISP based on nanoscheme, which will bring satisfaction both to me and others because OxyLISP will be right off almost as versatile as tinyscheme, equally easy to expand, and much much faster. I believe Oxygen has enough potential to keep OxyLISP's speed compatible with the gcc -Os nanoscheme.

But a few of current OxyLISP's features that are suitable for inclusion in SBLisp will be added to the latter and I'll post its sources here for you to transfer to the repo. You should understand that even so, it's not just a matter of copy-pasting; everything should be tested and it also takes time. Please be patient. If I said I would do it, I eventually will even though it's not on my top priority list.

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #850 on: September 26, 2014, 06:22:16 AM »
Hi Charles,

Lexicologically, nanoscheme is a complete implementation of R4RS standard of Scheme including its macro and call-with-current-continuation extensions. Numerically, it currently implements 32-bit integers (fixnums) only though its data type UDT and tagging system is easily expandable to accomodate other data types. Perhaps I will turn 32-bit fixnums to 64-bit fixnums (quads) and will add 64-bit flonums (doubles) when porting the code to Oxygen. Full "numeric tower" is possible later on by adding exact, complex, and bignum data types as well.
« Last Edit: September 26, 2014, 06:50:20 AM by Mike Lobanovsky »

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #851 on: September 26, 2014, 06:44:05 AM »
Hi Rob,

I will not disclose where I got the nanoscheme sources from. I can only tell you that "nanoscheme" is my own codename for it and it has nothing to do with its original name. Its author released it in the public domain officially so I am not obliged to name either him or his original creation. Nonetheless, nanoscheme based OxyLISP will go in the public domain as well and it will not bear any mention of my own name there. Perhaps it will even include a tribute to the original author, which, in my opinion, will be more than appropriate (though absolutely not required) under the circumstances.

There are no dialects in Russian. There is only humble speech of the peasantry, marginal lingo of the declassed, mixed parlance of the population that live on the Belarusian/Russian and Ukrainian/Russian borders (like in Donbass, for example), and educated, lofty speech of the intellectuals. The literary language of Saint-Petersburg is a recommended standard for both writing and pronunciation.
« Last Edit: September 27, 2014, 07:58:01 PM by Mike Lobanovsky »

JRS

  • Guest
Re: Lisp in Basic
« Reply #852 on: September 26, 2014, 11:52:36 AM »
Quote from: Mike
I will not disclose where I got the nanoscheme sources from.

Lets see if the KGB can make you talk.  :-X

JRS

  • Guest
Re: Lisp in Basic
« Reply #853 on: September 26, 2014, 01:38:11 PM »
What would be the preferred TinyScheme syntax for passing a list to a BASIC array?

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #854 on: September 26, 2014, 04:35:37 PM »
Lets see if the KGB can make you talk.  :-X

Actually they tried to four times in my life IIRC but failed. It wasn't Stalin's original KGB (called OGPU at those times) though. ;)

What would be the preferred TinyScheme syntax for passing a list to a BASIC array?

It would be OK if general syntax is

(foreign-call <BASIC-foo-name> [<param1> <param2> . . . <paramn>])

foreign-call can also be foreign-function. BASIC-foo-name is the name of the function or sub you're actually calling. Optional param's can be of any type that Tinyscheme can pass and BASIC can accept. Any of the param's can be distinct data objects (separate chars, numbers, strings), char and number vectors (i.e. arrays), or lists containing any of the aforementioned data objects in any combination. A param can also be an expression result, e.g. (+ 2 2) or the name of a variable that refers to any of the aforesaid objects, in which case the variable's value is passed as the actual parameter.

That's what I've seen in the LISP languages so far. Perhaps Rob can suggest something better.


P.S. Lists are usually expressed through the name of the variable that actually refers to the list in question, or through an expression that returns a list, e.g. (list 1 2 3 4 5). An empty list is denoted as () or '() and would evaluate to 0 in such a language as SB. In BASIC's that recognize pointers, an empty list would also evaluate to a void zero pointer, or NULL.
« Last Edit: September 26, 2014, 05:12:52 PM by Mike Lobanovsky »