Lamp

From Esolang
Jump to navigation Jump to search

Lamp is an imperative, boolean based, esoteric programming language.

Overview

Types

Since it is a boolean based language, all values in lamp are either on (true) or off (false). With that in mind, there are no types such as integers or strings, instead, the lamp language has two types: lamps and switches.

A lamp is a variable that is either on or off (just like a real life lamp). An example of lamp declaration would be:

lamp example on

This creates a lamp called example with the value on.

A switch is analogous to a real life switch, that has an on and off position. Each position in a switch can hold a value, but all switches have only two positions, no more, no less. A basic example of a switch declaration would be:

switch example (on off) 

This creates a switch that holds the value on in the first position (called the off position) and the value off in the second position (called the on position). To access the first value we can type "example.off" while to access the second value we can type "example.on". Simple, right? Now for the most interesting part. Switches can hold another switch instead of an on/off value, making nested switches not only viable, but essential in lamp programming. For example, we could declare a switch within a switch like this:

switch example (on (off on))

Now, when accessing the on position, the value would be not on or off, but the (off on) switch. To access an element within the inner switch (off element for the example), we can type the following: "example.on.off". A switch element that is not another switch is called a switch lamp, as it also stores on and off values, just like normal lamps.

It is possible to build switches in a variety of ways. We could build a switch from an element of a bigger switch by typing the following code:

switch example_a (on (off on))
switch example_b example_a.on

This code creates a switch called example_b with the value (off on), based on the element in the on position of the switch example_a. We can also reference individual lamps and switch lamps inside a switch declaration, for example:

switch example_a (on (off on))
lamp example_b on
switch example_c (example_b example_a.on.off)

This code generates a switch called example_c with the value (on off), based on the references to the lamp example_b and the switch lamp example_a.on.off. Note that mixing these two ways to make switches is not supported. If you try to make a switch like "switch example_b (example_a example_a.off)", this will lead to an error, as example_a is not a lamp or a switch lamp, but a switch.

Displaying Values

There are two types of value displays, a block display and a word display. Word displays are inferred while block displays have to be explicited. For example, consider the following code:

lamp example on
display example

This code creates a lamp called example with the value on, and prints the word "on" on the screen. But displaying information to the user becomes boring if you can only say "on" and "off". This is why the block display exists! An example of a block display would be:

lamp example on
display block example

This would print a "█" on the screen.

Now you know about block displays, but they are kind of useless for single lamps. Let's talk about displaying switches! They are displayed the same way as lamps and can also be displayed in blocks and words. Pairing block displays with switches gives you a creative way to draw on the display.

Namespaces

The lamp programming language supports namespaces. Namespaces are added to variables by inserting the namespace of the variable and its name after a ":". An example would be "lamp ex:example on", where "ex" is the namespace and "example" is the name of the lamp. Namespacing your variables allows you to have variables with the same name in multiple places on your code without getting lost. For example, the code below:

lamp a:example on
lamp b:example off
display a:example
will display "on"

A thing to note is that all variables have namespaces, even if implied. The default namespace for lamps is "lamp", while the default namespace for switch is "switch". The line of lamp code lamp example on will actually create a lamp example inside the "lamp" namespace, therefore it is the same as writing lamp lamp:example on. Namespacing may seem unnecessary given what you know about lamp so far, but it will come in handy in the next section.

Circuits

You know how in other programming languages we have functions or methods to divide code? In lamp, we call those circuits, and understanding how they work is paramount for you to be a good lamp programmer. Circuits are declared with the "circuit" keyword before the circuit name and end with the ground keyword. The code circuit example will define a circuit starting in the next statement, ending only when the ground of the circuit is found. A basic example of circuit definition would be:

circuit example_circ
  lamp example (on off)
  display example
ground

Ok, so you can write a circuit, great, now you need to learn how to call them! To execute code inside a circuit you have to type the word "power" followed by the circuit name and the "on" word, or a reference to a lamp with value on. If you type "power example_circ on", you can start the code inside the example circuit we made before. If you typed "power example_circ off", the circuit example_circ would not be called.

Where can I call a circuit? Anywhere, including inside itself. This gives versatility to the syntax, as circuit definitions between lines of code will be ignored by lampi until it is called (and will be ignored forever if there is no "power" statement).

Why do I have to put "on" in every circuit powering? Because, as you may have noticed, lamp language has no "if" statement, like most other languages do. The way to write an if statement in lamp is a clever trick involving circuits. The code:

power example_circ example_lamp
circuit example_circ
  lamp new on
  display new
ground

will only execute the circuit "example_circ" if the lamp "example_lamp" is on. Otherwise, it will not. This is the same as writing something like if(example_lamp) in other languages.

Now about namespaces and circuits. There is no variable scope in lamp, so it means that the code:

circuit example_circ
  lamp example on
  display example
ground

lamp example off
example_circ
display example

will display "on" two times, as both lamp assignment statements change the lamp "lamp:example". Using namespaces we can change the code to:

circuit example_circ
  lamp example_circ:example on
  display example_circ:example
ground

lamp example off
example_circ
display example

and now the displaying will show a "on" and a "off", since they both modify a lamp called example, but in different namespaces.

Examples

Printing the word "lamp"

power main on 

circuit print_lamp
    switch row0 (on  (off (off (off (off  (off (on  (on  (off  (off    (on  (off (off (on  (off      (on (on  (on  on))))))))))))))))))
    switch row1 (on  (off (off (off (off  (on  (off (off (on   (off    (on  (on  (on  (on  (off      (on (off (off on))))))))))))))))))
    switch row2 (on  (off (off (off (off  (on  (off (off (on   (off    (on  (off (off (on  (off      (on (on  (on  on))))))))))))))))))
    switch row3 (on  (off (off (off (off  (on  (on  (on  (on   (off    (on  (off (off (on  (off      (on (off (off off))))))))))))))))))
    switch row4 (on  (on  (on  (on  (off  (on  (off (off (on   (off    (on  (off (off (on  (off      (on (off (off off))))))))))))))))))
    display block row0 
    display block row1
    display block row2
    display block row3
    display block row4
    delete switch row0
    delete switch row1
    delete switch row2
    delete switch row3
    delete switch row4
ground

circuit main
    power print_lamp on
ground

Logical AND

circuit and
    power and_arg0_on and:arg0
    circuit and_arg0_on
        lamp and:return and:arg1
    ground
    power and_arg0_off -and:arg0
    circuit and_arg0_off
        lamp and:return off
    ground
ground

lamp and_arg0 on
lamp and_arg1 off
power and on

External Resources

Lamp/lampi Github Repository