lux/host

Types

Boolean-Array

(type: Boolean-Array
  (host [Z))

Byte-Array

(type: Byte-Array
  (host [B))

Char-Array

(type: Char-Array
  (host [C))

Double-Array

(type: Double-Array
  (host [D))

Float-Array

(type: Float-Array
  (host [F))

Int-Array

(type: Int-Array
  (host [I))

Long-Array

(type: Long-Array
  (host [J))

Short-Array

(type: Short-Array
  (host [S))

Macros

!!!

## Takes a (Maybe ObjectType) and returns a ObjectType.
## A #;None would get translated into a (null).
(!!! (??? (: java.lang.Thread (null))))

## =>
(null)

(!!! (??? "YOLO"))

## =>
## YOLO

???

## Takes a (potentially null) ObjectType reference and creates a (Maybe ObjectType) for it.
(??? (: java.lang.String (null)))

## =>
#lux;None

(??? "YOLO")

## =>
(#lux;Some"YOLO")

array

## Create an array of the given type, with the given size.
(array Object +10)

array-length

## Gives the length of an array.
(array-length my-array)

array-load

## Loads an element from an array.
(array-load 10 my-array)

array-store

## Stores an element into an array.
(array-store 10 my-object my-array)

class-for

## Loads the class as a java.lang.Class object.
(class-for java.lang.String)

class:

## Allows defining JVM classes in Lux code.
## For example:
(class: #final (JvmPromise A) []

  (#private resolved boolean)
  (#private datum A)
  (#private waitingList (java.util.List lux.Function))

  (#public [] new [] []
           (exec (:= .resolved false)
             (:= .waitingList (ArrayList.new []))
             []))
  (#public [] resolve [{value A}] boolean
           (let [container (.new! [])]
             (synchronized _jvm_this
               (if .resolved
                 false
                 (exec (:= .datum value)
                   (:= .resolved true)
                   (let [sleepers .waitingList
                         sleepers-count (java.util.List.size [] sleepers)]
                     (map (lambda [idx]
                            (let [sleeper (java.util.List.get [(l2i idx)] sleepers)]
                              (Executor.execute [(@runnable (lux.Function.apply [(:! Object value)] sleeper))]
                                                executor)))
                          (i.range 0 (i.dec (i2l sleepers-count)))))
                   (:= .waitingList (null))
                   true)))))
  (#public [] poll [] A
           .datum)
  (#public [] wasResolved [] boolean
           (synchronized _jvm_this
             .resolved))
  (#public [] waitOn [{callback lux.Function}] void
           (synchronized _jvm_this
             (exec (if .resolved
                     (lux.Function.apply [(:! Object .datum)] callback)
                     (:! Object (java.util.List.add [callback] .waitingList)))
               [])))
  (#public #static [A] make [{value A}] (lux.concurrency.promise.JvmPromise A)
           (let [container (.new! [])]
             (exec (.resolve! (:! (host lux.concurrency.promise.JvmPromise [Unit]) container) [(:! Unit value)])
               container))))

## The vector corresponds to parent interfaces.
## An optional super-class can be specified before the vector. If not specified, java.lang.Object will be assumed.
## Fields and methods defined in the class can be used with special syntax.
## For example:
## .resolved, for accessing the "resolved" field.
## (:= .resolved true) for modifying it.
## (.new! []) for calling the class's constructor.
## (.resolve! container [value]) for calling the "resolve" method.

do-to

## Call a variety of methods on an object; then return the object.
(do-to vreq
  (HttpServerRequest.setExpectMultipart [true])
  (ReadStream.handler [(object [(Handler Buffer)]
                         []
                         ((Handler A) (handle [buffer A]) void
                          (lux/codata/io;run(do Monad<IO>
                                    [_ (write (Buffer.getBytes [] buffer) body)]
                                    (wrap [])))))])

  (ReadStream.endHandler [[(object [(Handler Void)]
                             []
                             ((Handler A) (handle [_ A]) void
                              (exec (do Monad<Promise>
                                      [#let [_ (lux/codata/io;run(close body))]
                                       response (handler (request$ vreq body))]
                                      (respond! response vreq))
                                [])))]]))

instance?

## Checks whether an object is an instance of a particular class.
## Caveat emptor: Can't check for polymorphism, so avoid using parameterized classes.
(instance? String "YOLO")

interface:

## Allows defining JVM interfaces.
(interface: TestInterface
  ([] foo [boolean String] void #throws [Exception]))

jvm-import

## Allows importing JVM classes, and using them as types.
## Their methods, fields and enum options can also be imported.
## Also, classes which get imported into a module can also be referred-to with their short names in other macros that require JVM classes.
## Examples:
(jvm-import java.lang.Object
  (new [])
  (equals [Object] boolean)
  (wait [int] #io #try void))

## Special options can also be given for the return values.
## #? means that the values will be returned inside a Maybe type. That way, null becomes #;None.
## #try means that the computation might throw an exception, and the return value will be wrapped by the Error type.
## #io means the computation has side effects, and will be wrapped by the IO type.
## These options must show up in the following order [#io #try #?] (although, each option can be used independently).
(jvm-import java.lang.String
  (new [(Array byte)])
  (#static valueOf [char] String)
  (#static valueOf #as int-valueOf [int] String))

(jvm-import #long (java.util.List e)
  (size [] int)
  (get [int] e))

(jvm-import (java.util.ArrayList a)
  ([T] toArray [(Array T)] (Array T)))

## #long makes it so the class-type that is generated is of the fully-qualified name.
## In this case, it avoids a clash between the java.util.List type, and Lux's own List type.
(jvm-import java.lang.Character$UnicodeScript
  (#enum ARABIC CYRILLIC LATIN))

## All enum options to be imported must be specified.
(jvm-import #long (lux.concurrency.promise.JvmPromise A)
  (resolve [A] boolean)
  (poll [] A)
  (wasResolved [] boolean)
  (waitOn [lux.Function] void)
  (#static [A] make [A] (JvmPromise A)))

## It should also be noted, the only types that may show up in method arguments or return values may be Java classes, arrays, primitives, void or type-parameters.
## Lux types, such as Maybe can't be named (otherwise, they'd be confused for Java classes).
## Also, the names of the imported members will look like ClassName.MemberName.
## E.g.:
(Object.new [])

(Object.equals [other-object] my-object)

(java.util.List.size [] my-list)

Character$UnicodeScript.LATIN

null

## Null object reference.
(null)

object

## Allows defining anonymous classes.
## The 1st vector corresponds to parent interfaces.
## The 2nd vector corresponds to arguments to the super class constructor.
## An optional super-class can be specified before the 1st vector. If not specified, java.lang.Object will be assumed.
(object [java.lang.Runnable]
  []
  (java.lang.Runnable (run) void
                      (exec (do-something some-input)
                        [])))

synchronized

## Evaluates body, while holding a lock on a given object.
(synchronized object-to-be-locked
  (exec (do-something ...)
    (do-something-else ...)
    (finish-the-computation ...)))

try

## Covers the expression in a try-catch block.
## If it succeeds, you get (#;Right result).
## If it fails, you get (#;Left error+stack-traces-as-text).
(try (risky-computation input))

with-open

## Creates a local-binding with the desired resources, and runs the body (assumed to be in the IO type).
## Afterwards, closes all resources (assumed to be subclasses of java.io.Closeable), and returns the value resulting from running the body.
(with-open [my-res1 (res1-constructor ...)
            my-res2 (res1-constructor ...)]
  (do Monad<IO>
    [foo (do-something my-res1)
     bar (do-something-else my-res2)]
    (do-one-last-thing foo bar)))

Values

(b2l value)

## Type converter.
## From:
java.lang.Byte

## To:
java.lang.Long

(-> (host java.lang.Byte) (host java.lang.Long))

(c2b value)

## Type converter.
## From:
java.lang.Character

## To:
java.lang.Byte

(-> (host java.lang.Character) (host java.lang.Byte))

(c2i value)

## Type converter.
## From:
java.lang.Character

## To:
java.lang.Integer

(-> (host java.lang.Character) (host java.lang.Integer))

(c2l value)

## Type converter.
## From:
java.lang.Character

## To:
java.lang.Long

(-> (host java.lang.Character) (host java.lang.Long))

(c2s value)

## Type converter.
## From:
java.lang.Character

## To:
java.lang.Short

(-> (host java.lang.Character) (host java.lang.Short))

(d2f value)

## Type converter.
## From:
java.lang.Double

## To:
java.lang.Float

(-> (host java.lang.Double) (host java.lang.Float))

(d2i value)

## Type converter.
## From:
java.lang.Double

## To:
java.lang.Integer

(-> (host java.lang.Double) (host java.lang.Integer))

(d2l value)

## Type converter.
## From:
java.lang.Double

## To:
java.lang.Long

(-> (host java.lang.Double) (host java.lang.Long))

(f2d value)

## Type converter.
## From:
java.lang.Float

## To:
java.lang.Double

(-> (host java.lang.Float) (host java.lang.Double))

(f2i value)

## Type converter.
## From:
java.lang.Float

## To:
java.lang.Integer

(-> (host java.lang.Float) (host java.lang.Integer))

(f2l value)

## Type converter.
## From:
java.lang.Float

## To:
java.lang.Long

(-> (host java.lang.Float) (host java.lang.Long))

(i2b value)

## Type converter.
## From:
java.lang.Integer

## To:
java.lang.Byte

(-> (host java.lang.Integer) (host java.lang.Byte))

(i2c value)

## Type converter.
## From:
java.lang.Integer

## To:
java.lang.Character

(-> (host java.lang.Integer) (host java.lang.Character))

(i2d value)

## Type converter.
## From:
java.lang.Integer

## To:
java.lang.Double

(-> (host java.lang.Integer) (host java.lang.Double))

(i2f value)

## Type converter.
## From:
java.lang.Integer

## To:
java.lang.Float

(-> (host java.lang.Integer) (host java.lang.Float))

(i2l value)

## Type converter.
## From:
java.lang.Integer

## To:
java.lang.Long

(-> (host java.lang.Integer) (host java.lang.Long))

(i2s value)

## Type converter.
## From:
java.lang.Integer

## To:
java.lang.Short

(-> (host java.lang.Integer) (host java.lang.Short))

(l2b value)

## Type converter.
## From:
java.lang.Long

## To:
java.lang.Byte

(-> (host java.lang.Long) (host java.lang.Byte))

(l2d value)

## Type converter.
## From:
java.lang.Long

## To:
java.lang.Double

(-> (host java.lang.Long) (host java.lang.Double))

(l2f value)

## Type converter.
## From:
java.lang.Long

## To:
java.lang.Float

(-> (host java.lang.Long) (host java.lang.Float))

(l2i value)

## Type converter.
## From:
java.lang.Long

## To:
java.lang.Integer

(-> (host java.lang.Long) (host java.lang.Integer))

(l2s value)

## Type converter.
## From:
java.lang.Long

## To:
java.lang.Short

(-> (host java.lang.Long) (host java.lang.Short))

(null? obj)

## Test for null object reference.
(null? (null))

## =>
true

(null? "YOLO")

## =>
false

(-> (host java.lang.Object) lux;Bool)

(resolve-class class)

## Given a potentially unqualified class name, qualifies it if necessary.
(resolve-class "String")

=>

## java.lang.String

(-> lux;Text (lux;Lux lux;Text))

(s2l value)

## Type converter.
## From:
java.lang.Short

## To:
java.lang.Long

(-> (host java.lang.Short) (host java.lang.Long))