Skip to content

AT-290690/fez

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

(let fizz-buzz (lambda n
    (cond
      (= (mod n 15) 0) "Fizz Buzz"
      (= (mod n 3) 0) "Fizz"
      (= (mod n 5) 0) "Buzz"
      (*) n)))

(|>
(math:range 1 100)
(array:map fizz-buzz)
(log!))
```

```lisp
(let Fizz (string char:F char:i char:z char:z))
(let Buzz (string char:B char:u char:z char:z))
(let FizzBuzz (string Fizz Buzz))

(let fizz-buzz (lambda n
    (cond
      (= (mod n 15) 0) FizzBuzz
      (= (mod n 3) 0) Fizz
      (= (mod n 5) 0) Buzz
      (*) n)))

  (|>
    (math:range 1 100)
    (array:map fizz-buzz)
    (log!))
; https://adventofcode.com/2020/day/1
(let *input*
(string
    char:1 char:7 char:2 char:1 char:new-line
    char:3 char:6 char:6 char:new-line
    char:2 char:9 char:9 char:new-line
    char:6 char:7 char:5 char:new-line
    char:1 char:4 char:5 char:6))
; solve part 1
(let solve (lambda arr cb
     (array:fold arr (lambda a b (do
        (let res (array:binary-search arr (cb b)))
        (if res (cons a (array res)) a)))
     ())))
; 514579
(|> *input*
    (string:lines)
    (array:map (lambda d (|> d (from:chars->digits) (from:digits->number))))
    (array:sort (lambda a b (> a b)))
    (solve (lambda x (- 2020 x)))
    (math:product)
    (log!))
(let *input* "1721,979,366,299,675,1456")
(let solve (lambda arr cb
     (array:fold arr (lambda a b (do
        (let res (array:binary-search arr (cb b)))
        (if res (cons a (array res)) a)))
     ())))
(|> *input*
    (string:commas)
    (array:map (lambda d (|> d (from:chars->digits) (from:digits->number))))
    (array:sort (lambda a b (> a b)))
    (solve (lambda x (- 2020 x)))
    (math:product)
    (log!))
; https://leetcode.com/problems/maximum-count-of-positive-integer-and-negative-integer/description/
(let max-count-of (lambda nums
  (math:max
    (array:count-of nums math:positive?)
    (array:count-of nums math:negative?))))

(|>
  (array -2 -1 -1 0 0 1 2)
  (max-count-of)
  (log!)) ; 3
; remove duplicate elements in the arr
(let unique (lambda arr (|>
      (let sorted (array:sort arr (lambda a b (> a b))))
      (array:zip (math:sequence sorted))
      (array:select (lambda x (do
                  (let index (car (cdr x)))
                  (or (not index)
                  (not (= (array:get sorted (- index 1)) (array:get sorted index)))))))
      (array:map car))))
; tests
(assert
   (case (unique (array 1)) (array 1))
   (case (unique (array 1 2 2 4 5 9 5 12 14 1)) (array 1 2 4 5 9 12 14)))

Installation:

npm i fez-lisp
import { fez } from 'fez-lisp'
fez(`(log! "Hello World!")`) // Hello World!
import { fez } from 'fez-lisp'
fez(`(+ 1 (array 2))`) // Not all arguments of (+) are (number) (+ 1 (array 2))
import { fez } from 'fez-lisp'
eval(
  fez(
    `(|> 
        (math:range 1 11) 
        (array:map (lambda x (* x x))) 
        (log!)))`,
    // include standard library
    // compile fez to JavaScript
    // tree shake standard library
    { compile: true }
  )
)
import { fez } from 'fez-lisp'
fez(
  `
(let Fizz (string char:F char:i char:z char:z))
(let Buzz (string char:B char:u char:z char:z))
(let FizzBuzz (string Fizz Buzz))

(let fizz-buzz (lambda n
    (cond
      (= (mod n 15) 0) FizzBuzz
      (= (mod n 3) 0) Fizz
      (= (mod n 5) 0) Buzz
      (*) n)))

  (|> (math:range 1 100) (array:map fizz-buzz) (log!))`,
  { compile: false }
)

Many logical operators

(let logic-a (lambda a b
   (if (or (= b -1) (> a b)) char:a
       (if (and (> b 2) (< a 4)) char:b char:c))))

; De Morgan's First Law: ¬(P ∧ Q) is equivalent to (¬P ∨ ¬Q)
; De Morgan's Second Law: ¬(P ∨ Q) is equivalent to (¬P ∧ ¬Q)
(let logic-b (lambda a b
    ; Swapping the consequent with the alternative in the condition by using (unless) instead of (if)
    ; The condition (or (= b -1) (> a b)) has been changed to (and (not (= b -1)) (not (> a b))), applying De Morgan's First Law.
    ; The condition (and (> b 2) (< a 4)) has been changed to (or (not (> b 2)) (not (< a 4))), applying De Morgan's Second Law.
    (unless (and (not (= b -1)) (not (> a b))) char:a
            (unless (or (not (> b 2)) (not (< a 4))) char:b char:c))))

(assert
   (case (logic-a 0 -1) (logic-b 0 -1))
   (case (logic-a 1 3) (logic-b 1 3))
   (case (logic-a 1 2) (logic-b 1 2)))

Tail Call Optimization:

There are no loop constructs (like a "for" or "while" loop in other languages). That's because we don't quite need one: looping in fez is done by recursion — and the interpreter already supports that. But because each procedure call calls evaluate, recursing over a large number of items blows up the call stack of the interpreter.

This optimization technique works only by declaring the variable with let* and only when compiled to JavaScript.

(let rec:sum-to (lambda n acc (if (= n 0) acc (rec:sum-to (- n 1) (+ n acc)))))
(rec:sum-to 10000 0)
console.log(
  fez(
    `(let rec:sum-to (lambda n acc (if (= n 0) acc (rec:sum-to (- n 1) (+ n acc)))))
(rec:sum-to 10000 0)`,
    { compile: 1, eval: 1 }
  )
)
// 50005000

Pass tree source as text:

import { fez } from '../index.js'
const source = `(|> 
  (array 1 2 3 4)
  (math:permutations)
  (array:flat-one)
  (math:summation)
  (log!))`
fez(source, {
  mutation: 1
})

Pass tree instead of a source:

import { fez, tree, std } from '../index.js'
const source = `(|> 
  (array 1 2 3 4)
  (math:permutations)
  (array:flat-one)
  (math:summation)
  (log!))`
const ast = tree(source, std)
fez(ast, { mutation: 1 })

If passing AST and STD is not used then use tree with a single arugment

import { fez, tree } from '../index.js'
console.log(fez(tree(`(+ (|> 1 (+ 2) (* 3) (- 1)) (- (* (+ 1 2) 3) 1))`)))
; all keywords
(/) (+) (*) (-) (=) (<) (>) (>=) (<=) (&) (~) (|) (^) (<<) (>>) (>>>) (|>) (mod)
(atom?) (lambda) (array) (number) (string)
(array:set!) (array:get) (car) (cdr) (cons) (length) (do)
(if) (unless) (not) (and) (or) (cond)
(apply) (let) (case) (assert)
(log!) (log-string!) (clear!) (void) (fez-manual)

About

Lisp that compiles to JavaScript

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published