Author Topic: Lisp in Basic  (Read 226928 times)

0 Members and 3 Guests are viewing this topic.

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #210 on: August 07, 2014, 05:30:58 AM »
[UPD]

Charles,

And the following will be my final solution with both ACCUM and ARGS symbols eliminated and substituted for with a local var and an explicit vararg list, respectively:

Code: [Select]
(define average
  (lambda (input)
    (let ((accum 0))
      (for-each (lambda (x) (set! accum (+ accum x))) input)
      (print (/ accum (length input))) (newline)
    )
  )
)

(average (list 0 1 2 3 4 5 6 7 8 9))

Ta-daaa....!

[EDIT] Fixed with a shorter print statement thanks to RobbeK.
« Last Edit: August 07, 2014, 07:31:29 AM by Mike Lobanovsky »

Charles Pegge

  • Guest
Re: Lisp in Basic
« Reply #211 on: August 07, 2014, 06:00:37 AM »
Thanks Mike,

It will take me a while to unravel that construction, though. I have a mental block in understanding lambda. I am distracted by thoughts of young sheep whenever I see it.


Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #212 on: August 07, 2014, 06:26:05 AM »
The Lamb. Starts at 1:15. Used to be one of my favorites.

I once had a college mate, a spitting image of Phil Collins of Genesis. Bold and scary as hell but terrifically popular with roadies and chicks in general. Now lives somewhere in Canada. Lost track of him somehow a few years back though.

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #213 on: August 07, 2014, 06:39:22 AM »
A lambda is actually a LISP declaration for a C/BASIC/etc user-defined function. Thus

Code: [Select]
(define foo
(lambda (bar)
...
)
)

stands for the following pseudo:

Code: [Select]
declare function foo (bar)
...
end function

Lambdas can also be anonymous similar to C closures, in which case they lack the "define" component and the corresponding name/label (as "foo" above):

Code: [Select]
(lambda (bar) ... )
The bar argument/multiple arguments is/are optional in both cases however its/their enclosing parentheses are mandatory at all times in SB/FBSL LISP.

My average solution features the both lambda flavors - a named outer
Code: [Select]
(define average
  (lambda (input)
  ...
  )
)

and an anonymous inner

Code: [Select]
(lambda (x) ... )
that's applied successively to each element in the input argument list of the outer average lambda. Iteration is performed by the for-each directive which has a specific "inverted" syntax: (for-each (lambda-to-apply) (list-of-elements-to-apply-lambda-to)).
« Last Edit: August 07, 2014, 07:36:41 AM by Mike Lobanovsky »

RobbeK

  • Guest
Re: Lisp in Basic
« Reply #214 on: August 07, 2014, 07:00:25 AM »
Hi Mike,  ok   but has it "apply" or not ?   (all the Schemes I ever used, have it -- and probably it was there from the beginning .. Scheme is somewhat older than Common Lisp though )

in that case  it simplifies (without the "division by zero" check ) to

(/  (apply + L) (length L))  ...

"(print (set! accum (/ accum (length input))))"    -- (print (/ accum (length input)))  is shorter, not ?  accum is local , so it can't be recycled anyway , no need to assign it   just for printing   (?)

best Rob


Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #215 on: August 07, 2014, 07:17:08 AM »
Hi Rob,

apply is the first entry in the BASIC LISP dictionary of keywords. The manual can be found in the SB and FBSL LISP distros available for download at the respective sites, or you can also read and/or download it directly from the author's.

So yes, the apply construct may be used in SB/FBSL LISP and a check to avoid division by zero would be also welcome. I don't insist my solution is the best, or the shortest, or the most fool-proof, or the only one conceivable. It certainly isn't. But it is my solution, and I simply haven't had the time to try anything else. I still need to RTFM so very often... :)

And yes again, your (print (/ accum (length input))) suggestion is accepted with gratitude. It's definitely shorter while my assignment here was a piece of unnecessary extra bloat. The script is now fixed accordingly. :)
« Last Edit: August 07, 2014, 07:29:41 AM by Mike Lobanovsky »

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #216 on: August 07, 2014, 07:51:53 AM »
!!! TA-DAAA AGAIN !!!

Here comes Rob's version of variadic average with one less lambda and one less local var but the exact same functionality:

Code: [Select]
(define average
  (lambda (input)
    (print (/ (apply + input) (length input))) (newline)
  )
)

(average (list 0 1 2 3 4 5 6 7 8 9))

Welcome to the ranks, Rob! :D



.
« Last Edit: August 07, 2014, 08:02:53 AM by Mike Lobanovsky »

JRS

  • Guest
Re: Lisp in Basic
« Reply #217 on: August 07, 2014, 08:53:01 AM »
Quote from: Mike
or you can also read and/or download it directly from the author's.

Correction:  or you can also read and download a broken/incomplete copy directly from the author's site.

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #218 on: August 07, 2014, 08:59:59 AM »
I beg your pardon?

19/19 pages are an incomplete manual?

JRS

  • Guest
Re: Lisp in Basic
« Reply #219 on: August 07, 2014, 09:18:58 AM »
Oh. I thought you were referring to the code.


Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #220 on: August 07, 2014, 09:32:52 AM »
That's correct. The manual is precise, complete and instructive though somewhat laconic. OTOH the QB 4.5 source code is both uncompilable and buggy.

John and I have been able to fix it in our respective SB and FBSL scripts though to be compliant with the accompanying manual.

RobbeK

  • Guest
Re: Lisp in Basic
« Reply #221 on: August 07, 2014, 10:21:16 AM »
Great Mike !

I think "apply" must be a macro ,   the primitive being :

(eval (cons an-operator a-list))

ran next in Bigloo Scheme and it works the same as in Common Lisp and Newlisp

(eval (cons +  (list 4 5 6)))  :::  identical with  (apply + (list 4 5 6)) 
in steps
(cons + (list 4 5 6))>  (+ 4 5 6)
(eval .. ) forces the evaluation , making it the anti-thesis of  '    (quote ...) which prohibits evaluation. 

now the next step in Lisp is mapping ..  (a picture shows more than 1000s words ->)

(map (lambda (x) (/ 1 x)) (list 1 2 3))  ->  ( 1  1/2 1/3 )

with apply and map, you have two of the most powerful tools of Lisp  ;)

best Rob !!




JRS

  • Guest
Re: Lisp in Basic
« Reply #222 on: August 07, 2014, 10:24:33 AM »
I like the new load method Mike suggested.

Code: [Select]
jrs@laptop:~/sb/sb22/sblisp$ scriba lisp.sb
Initializing Memory...
Initializing Lisp Environment...
LISP in BASIC v1.3 by Arthur Nunes-Harwitt
0](load 'AVE.SCM)
AVE.SCM  1
(define average
  (lambda (input)
    (print (/ (apply + input) (length input))) (newline)
  )
)
AVERAGE

(average (list 0 1 2 3 4 5 6 7 8 9))
4.500000
T
T
0]

Mike Lobanovsky

  • Guest
Re: Lisp in Basic
« Reply #223 on: August 07, 2014, 10:39:05 AM »
@Rob:

Thanks a lot for the heads-up! I'll try the cons trick later on tonight and will publish my results here.


@John:

The ' trick is implicit in the BASIC LISP code that's why I didn't notice it immediately. But it's commonplace in LISP and can substitute (quote something) at all times. In fact, it is a very handy shorthand.

JRS

  • Guest
Re: Lisp in Basic
« Reply #224 on: August 07, 2014, 03:56:44 PM »
I was able to solve the SBLisp file name having to be upper case issue.

DoLoad:
Code: [Select]
  lispfilename = symbols[pvalue]
  OPTION COMPARE sbCaseInsensitive
  fnpos = INSTR(ibuf, lispfilename)
  IF fnpos THEN lispfilename = MID(ibuf, fnpos, LEN(lispfilename))
  OPTION COMPARE sbCaseSensitive

Testing
Code: [Select]
jrs@laptop:~/sb/sb22/sblisp$ scriba lisp.sb
Initializing Memory...
Initializing Lisp Environment...
LISP in BASIC v1.3 by Arthur Nunes-Harwitt
0](load 'Ave.scm)
Ave.scm  1
(define average
  (lambda (input)
    (print (/ (apply + input) (length input))) (newline)
  )
)
AVERAGE

(average (list 0 1 2 3 4 5 6 7 8 9))
4.500000
T
T
0]