25.09.2007 14:12
- oppdatert 230 dager siden av Terje Pedersen
Colon: Distribuert Colon
For å muliggjøre noen av de tingene jeg har lyst til å få til når når kompilator og VM for Colon er på plass så trenger jeg også muligheten for å distribuert programmering.
En enkel forklaring på distribuert programmering er når du surfer på nettet så sender du en forespørsel til en eller annen server som så returnerer den siden du spurte etter.
Når jeg så tenker på mobiltelefoner oppi det hele her så tenker jeg f.eks. på muligheter som kjapt å kode noe som bruker hva jeg normalt bare har tilgang til på serveren eller som en mulighet for enkelt og greit å lage multiplayer-spill mellom mobiltelefoner.
Utskrift av det som blir sendt til server
- # on server side 192.168.0.2
- "dcolon://:7777/echo" service
- server: receive
- "Echo @0" out
- server
- # client side 192.168.0.30
- "dcolon://192.168.0.2:7777/echo" open :pid
- "message" pid send
Sende kode for kjøring på serveren
- # server 192.168.0.2
- "dcolon://:7777/code" service
- server: receive
- {code _} = ? tail call drop
- server
- # client 192.168.0.30
- "dcolon://192.168.0.2:7777/code" open :pid
- {code {"Hello World on server!" out}} pid send
Kjøre “uptime” på serveren og returnere svaret
- # server 192.168.0.2
- "dcolon://:7777/uptime" service
- server: receive
- {uptime pid} = ? "uptime" system pid send drop
- server
- # client 192.168.0.30
- "dcolon://192.168.0.2:7777/uptime" open :pid
- {uptime @self} pid send receive "Uptime from server: @0" out
permalink |
kommentarer (0)
25.09.2007 11:33
- oppdatert 230 dager siden av Terje Pedersen
Colon: GUI
Hvordan en skal beskrive GUI-kode i Colon er jeg fortsatt litt usikker på, men ting begynner å ta en eller annen form i alle fall.
Eksempel 1:
En enkelt knapp med teksten “Say hello” på som når den trykkes på skriver ut “Hello, World!”.
- sayhello: receive "Hello, World!" out sayhello
- {"Say hello"} ¤sayhello gbutton "Say hello" gwindow gmain
Eksempel 2:
Tre knapper plassert vertikalt med tekstene “1”, “2” og “3” på som når du trykker på “1” oppdaterer teksten på “1” til “wee” og når du trykker på “2” eller “3” skriver ut at du trykket på den respektive knappen.
- buttonpressed: receive
- {one _} = ? "Button one pressed" out tail {one: "wee"} swap send
- {two _} = ? "Button two pressed" out
- {three _} = ? "Button three pressed" out
- buttonpressed
- {one: "1" two: "2" three: "3"} ¤buttonpressed gbutton gvbox "The buttons" gwindow gmain
Så noen eksempler med å hente ut verdier fra de forskjellige GUI-elementene når ting skjer. Det jeg har tenkt foreløpig er at du kan sende en get melding til pid om hva du vil ha.
- {get texta textb} -> {get pid {texta: "mmm" textb: "yess"}}
- {get celsius} -> {get pid {celsius: "30"}}
- {get values: @inputvalues} -> {get pid {values: {1 4 6 7 8}}}
- {get @inputvalues} -> {get pid {1 4 6 7 8}}
Eksempel 3
Dette eksempelet viser en øverst en tekst deretter fem tekstbokser vertikalt samt en “Average”-knapp nederst som når den blir trykket på kalkulerer snittet på de fem tallene og gir svaret i det øverste tekst-elementet.
- calculate: receive
- {calculate pid} = ? {get @inputvalues} pid send drop
- {get pid _} = ? tail 0 swap | + ; 5 / {display: @0} pid send drop
- {{display: "0"} glabel
- {} 1 5 to | "" + ; gtextbox !inputvalues
- {"Calculate average"} ¤calculate gbutton}
- gvbox "Average" gwindow gmain
Eksempel 4
Et lite eksempel for å omforme Farhenheit til Celsius.
- f2c: 32 - 5 9 / *
- calculate: receive
- {convert pid} = ? {get celsius} pid send drop
- {get pid _} = ? tail . celsius f2c {display: @0} pid send drop
- calculate
- {{display: "0"} glabel
- {celsius: ""} gtextbox
- {convert: "Convert"} ¤calculate gbutton}
- gvbox "F2C" gwindow gmain
Om det er slik det blir til slutt gjenstår å se da det ikke alltid er så lett å vite når alle detaljer om hva som går an å gjøre og hva som ikke går an før kompilator/vm fungerer.
permalink |
kommentarer (0)
24.09.2007 15:53
- oppdatert 230 dager siden av Terje Pedersen
Colon: Tegnbruk
I Colon kan ! brukes istedenfor : foran ord som da betyr at en lagrer innholdet i ordet slik som for : men at en ikke konsumerer det fra stacken.
En annen måte å se det på er at !name = dup :name Normalt liker jeg ikke for mye “syntax sugar” som gjør språk mye mer kompliserte, men akkurat dette tilfellet vil jeg ikke ha dup der når dette ordet bare skal brukes senere og ikke har noe med der det står for å si det på den måten.
- # gjennomsnitt
- 0 {1 2 3} !l | + ; l length /
Oversikt
Slik som dette ser det ut foreløpig over hvilke tegn en kan bruke foran og etter ord i Colon og hva dem betyr:| Tegn | Betydning |
|---|---|
| name: | definisjon av ord |
| nameX | repeter name X antall ganger, f.eks. dup3 tail2 |
| :name | pop fra stack og lagre i name (a ->) |
| !name | dup :name (a -> a) |
| ¤name eller ¤{...} | ny concurrent prosess, pid på stack (-> pid) |
| ”@X @name” {@X @name} | pop posisjon X fra stack @0 = først, @name kjør name pop svar fra stack, sett inn i streng / blokk |
| +name | name + :name (+:name eller +name ?) |
Burde kanskje bytte til +name fordi muligens : også kan brukes når en skal bruke moduler samt greit å holde seg til enkle regler som kun ett tegn foran eller etter ord
Sammenligning
| Tegn | Betydning | Eksempel # på stack |
|---|---|---|
| > | større enn | 10 5 > # 10 true |
| < | mindre enn | 10 5 < # 10 false |
| ≠ | ulik | 10 5 ≠ # 10 true |
| = | lik | 10 5 = # 10 false |
Aritmetikk
| Tegn | Betydning | Eksempel # på stack |
|---|---|---|
| + | addisjon | 10 5 + # 15 |
| - | subtraksjon | 10 5 – # 5 |
| / | divisjon | 10 5 / # 2 |
| * | multiplikasjon | 10 5 * # 50 |
| % | modulo | 10 5 % # 0 |
permalink |
kommentarer (0)
24.09.2007 08:57
- oppdatert 231 dager siden av Terje Pedersen
Colon: Concurrency
For hendelser i Colon har jeg bestemt meg for å bruke concurrency, ikke ulikt ifra Erlang. GUI-eksempler kommer jeg tilbake til senere når jeg har ting mer klart.
Concurrency i Colon bruker tegnet for currency ¤_ foran et ord eller en blokk _{} for å utføre dette i en egen concurrent prosess. I tillegg brukes ordene receive og send.
- sayhello: "Hello World!" out
- ¤sayhello
- -> Hello World!
- sayreceived: receive "Received @0" out
- 5 ¤sayreceived send
- -> Received 5
- saymulti: receive
- {ok} = ? "OK" out
- {warning _} = ? "Warning: @0" out
- saymulti
- ¤saymulti :pid
- # ...
- {warning "battery low"} pid send
- -> Warning: battery low
- ¤{"Hello World!" out}
- -> Hello World!
Et større eksempel
Her er et x^y concurrency eksempel fra Erlang jeg satt og lekte meg med og det ble som følger i Colon:
- pow: {N M} = ?
- {} {@self @M} powspawn | N swap send + ;
- 1 swap | drop receive *
- powspawn:
- {Pid 0} = ? {} ¤{receive 1 @Pid send} +
- {Pid M} = ?
- ¤{receive @Pid send}
- {@Pid @M 1 -} powspawn +
Hvorvidt dette er helt riktig vet jeg sannelig ikke, er ikke alltid like enkelt når ting er i endring å samtidig la hjernen leke både kompilator og VM på engang ;-)
Erlang:
- pow(N, M) ->
- Pids = pow_spawns(self(),M),
- Vals = lists:map(fun(P) -> P ! N end, Pids),
- lists:foldl(
- fun(_,Total) -> receive X -> X*Total end end,
- 1, Vals).
- pow_spawn(Pid,0) ->
- [spawn(fun() -> receive _ -> Pid ! 1 end end)];
- pow_spawn(Pid,M) ->
- [spawn(fun() -> receive X -> Pid ! X end end)
- | spawn(pow_span(Pid,M-1))].
permalink |
kommentarer (0)
22.09.2007 00:13
- oppdatert 230 dager siden av Terje Pedersen
Colon: vs PHP
Tenkte jeg skulle presentere noen små eksempler på hvordan Colon kode ser ut i forhold til PHP i da typiske PHP måter å gjøre ting på.
konkatinering av strenger
Colon
- txtone: "Hello World"
- txttwo: "1234"
- txtone " " txttwo +2 out
PHP
- $txt1="Hello World";
- $txt2="1234";
- echo $txt1 . " " . $txt2;
if
Colon
- "Fri" "D" date = ?
- "Hello!" out
- "Have a nice weekend!" out
- "See you on Monday!" out
PHP
- $d=date("D");
- if ($d=="Fri")
- {
- echo "Hello!<br />";
- echo "Have a nice weekend!";
- echo "See you on Monday!";
- }
if/else/else
Colon
- "D" date
- "Fri" = ?
- "Have a nice weekend!" out
- "Sun" = ?
- "Have a nice Sunday!" out
- : "Have a nice day!" out
PHP
- $d=date("D");
- if ($d=="Fri")
- echo "Have a nice weekend!";
- elseif ($d=="Sun")
- echo "Have a nice Sunday!";
- else
- echo "Have a nice day!";
switch type konstruksjon
Colon
- x
- 1 = ? "Number 1" out
- 2 = ? "Number 2" out
- 3 = ? "Number 3" out
- : "No number between 1 and 3" out
PHP
- switch ($x)
- {
- case 1:
- echo "Number 1";
- break;
- case 2:
- echo "Number 2";
- break;
- case 3:
- echo "Number 3";
- break;
- default:
- echo "No number between 1 and 3";
- }
hente ut navn fra en array
Colon
- names: {"Peter" "Quagmire" "Joe"}
- names | ; "@1 and @0 are @2's neighbors" out
PHP
- $names[0] = "Peter";
- $names[1] = "Quagmire";
- $names[2] = "Joe";
- echo $names[1] . " and " . $names[2] .
- " are ". $names[0] . "'s neighbors";
hente ut alder fra hash type array
Colon
- ages: {Peter: 32 Quagmire: 30 Joe: 34}
- ages . "Peter is @Peter years old." out
PHP
- $ages['Peter'] = "32";
- $ages['Quagmire'] = "30";
- $ages['Joe'] = "34";
- echo "Peter is " . $ages['Peter'] . " years old.";
while løkke ikke eget ord for det i Colon, men kan alikvell gjøres
Colon
- i: 1
- loop: i 5 <= ? "The number is @0" out 1 +i loop
PHP
- $i=1;
- while($i<=5)
- {
- echo "The number is " . $i;
- $i++;
- }
do while løkke som i likhet med while løkke ikke finnes eget ord for i Colon
Colon
- i: 0
- loop: 1 +i "The number is @i" out i 5 < ? drop loop
PHP
- $i=0;
- do
- {
- $i++;
- echo "The number is " . $i;
- }
- while ($i<5>
for løkke ved hjelp av en to generator i Colon
Colon
- 1 5 to | "Hello World!<br />" out
PHP
- for ($i=1; $i<=5; $i++)
- {
- echo "Hello World!<br />";
- }
foreach løkke i Colon brukes |
Colon
- arr: {"one" "two" "three"}
- arr | "Value: @0<br />" out
PHP
- $arr=array("one", "two", "three");
- foreach ($arr as $value)
- {
- echo "Value: " . $value . "<br />";
- }
funksjon ord i Colon
Colon
- writeMyName: "@0 Pedersen.<br />" out
- "My name is " outnb
- "Terje" writeMyName
PHP
- function writeMyName($fname)
- {
- echo $fname . " Pedersen.<br />";
- }
- echo "My name is ";
- writeMyName("Terje");
addisjonsfunksjon med to parametre
Colon
- add: +
- 1 16 add "1 + 16 = @0" out
PHP
- function add($x,$y)
- {
- $total = $x + $y;
- return $total;
- }
- echo "1 + 16 = " . add(1,16)
try/catch
Colon
- checkNum: 1 > ? "Value must be 1 or below" throw : true
- ! 2 checkNum "If you see this, the number is 1 or below" out
- : "Message @0" out
PHP
- function checkNum($number)
- {
- if($number>1)
- {
- throw new Exception("Value must be 1 or below");
- }
- return true;
- }
- try
- {
- checkNum(2);
- echo 'If you see this, the number is 1 or below';
- }
- catch(Exception $e)
- {
- echo 'Message: ' .$e->getMessage();
- }
litt MySQL
Colon
- ! "mysql://peter:abc123@localhost/my_db" open :con
- : "Could not connect: @0" bye
- "SELECT * FROM person" con query | .
- "@FirstName @LastName<br />" out
PHP
- $con = mysql_connect("localhost","peter","abc123");
- if (!$con)
- {
- die('Could not connect: ' . mysql_error());
- }
- mysql_select_db("my_db", $con);
- $result = mysql_query("SELECT * FROM person");
- while($row = mysql_fetch_array($result))
- {
- echo $row['FirstName'] . " " . $row['LastName'];
- echo "<br />";
- }
array/tekst implode
Colon
- pieces: {"Hello" "World," "I" "am" "Here!"}
- gluedTogetherSpaces: pieces " " join
- gluedTogetherDashes: pieces "-" join
- pieces | "Piece #@key = @0 <br />" out
- "Glued with Spaces = @gluedTogetherSpaces <br />" out
- "Glued with Dashes = @gluedTogetherDashes <br />" out
PHP
- $pieces = array("Hello", "World,", "I", "am", "Here!");
- $gluedTogetherSpaces = implode(" ", $pieces);
- $gluedTogetherDashes = implode("-", $pieces);
- for($i = 0; $i < count($pieces); $i++){
- echo "Piece #$i = $pieces[$i] <br />";
- }
- echo "Glued with Spaces = $gluedTogetherSpaces <br />";
- echo "Glued with Dashes = $gluedTogetherDashes";
key/value
Colon
- employeeAges: {Lisa: 28 Jack: 16 Ryan: 35 Rachel: 46 Grace: 34}
- employeeAges | "Name: @key, Age: @0 <br />" out
PHP
- $employeeAges;
- $employeeAges["Lisa"] = "28";
- $employeeAges["Jack"] = "16";
- $employeeAges["Ryan"] = "35";
- $employeeAges["Rachel"] = "46";
- $employeeAges["Grace"] = "34";
- foreach( $employeeAges as $key => $value){
- echo "Name: $key, Age: $value <br />";
- }
multiple for løkker som utfører samme kode
Colon
- 0 3 to 10 13 2 tostep + |
- "Number: @0" out
PHP
- for($i = 0; $i < 4; $i++) {
- echo "Number: " . $i;
- }
- for($i = 10; $i < 14; $i += 2){
- echo "Number: " . $i;
- }
permalink |
kommentarer (0)
18.09.2007 20:32
- oppdatert 237 dager siden av Terje Pedersen
Colon: Funksjonelle egenskaper
I funksjonelle språk kan du f.eks. gi funksjoner som parameter til en annen funksjon, en har navnløse funksjoner og en har ofte funksjoner som map/filter/reduce eller tilsvarende.
Har prøvd meg på noen eksempler med Ruby nå. Mest for å sjekke hvordan det ser ut i Colon samt sjekke at ting er mulige å gjøre slik det er nå eller om jeg mangler noe.
Colon – funksjon som parameter
- each: :b | b call
- {1 2 3} {out} each
Ruby
- def each(array, block)
- array.each{|e| block.call(e) }
- end
- block = Proc.new{|e| puts e }
- each([1,2,3], block)
map/reduce/filter
Det en kan legge merke til er at det ikke finnes noen egne ord/funksjoner for map/reduce/filter eller for den saks skyld de andre nedenfor da alt løses ved hjelp av ? : ;; og | Eneste nye fra forrige Colon innlegg er ;; som betyr at den dropper å gå gjennom flere elementer mao en slutter |
Colon – map
- {} {1 2 3 4} | 1 +2
- -> {2 3 4 5}
Ruby
- [1,2,3,4].map{|n| n+1 }
- -> [2 3 4 5]
Colon – filter
- {} {1 2 3 4 5 6 7 8 9 10} | dup 2 % 0 = ? drop +
- -> {2 4 6 8 10}
Ruby
- [1,2,3,4,5,6,7,8,9,10].select{|n| n % 2 == 0 }
- -> [2,4,6,8,10]
Colon – reduce
- 0 {1 2 3 4 5} | +
- -> 15
Ruby
- [1,2,3,4,5].inject(0){|sum,n| sum + n }
- -> 15
Diverse andre
Ruby har flere slike funksjoner så her noen Colon eksempel på flere av dem.
Colon – find
- {1 2 3 4} | 2 > ? ;; : drop nil
- -> 3
- {1 2 3 4} | 78 = ? ;; : drop nil
- -> nil
Ruby
- [1,2,3,4].find{|n| n > 2 }
- -> 3
- [1,2,3,4].find{|n| n == 78 }
- -> nil
Colon – all
- true {1 2 3 4 5} | 10 > ? drop not ;;
- -> true
- true {1 2 3 4 5} | 4 > ? drop not ;;
- -> false
Ruby
- [1,2,3,4,5].all?{|n| n < 10 }
- -> true
- [1,2,3,4,5].all?{|n| n < 4 }
- -> false
Colon – include
- false {1 2 3 4 5} | 3 = ? drop not ;;
- -> true
- false {1 2 3 4 5} | 10 = ? drop not ;;
- -> false
Ruby
- [1,2,3,4,5].include?(3)
- -> true
- [1,2,3,4,5].include?(10)
- -> false
Colon – reject
- {} 1 10 to | dup 3 % 0 = ? : drop +
- -> {1 2 4 5 7 8 10}
Ruby
- (1..10).reject {|i| i % 3 == 0}
- -> [1, 2, 4, 5, 7, 8, 10]
permalink |
kommentarer (0)
17.09.2007 13:08
- oppdatert 238 dager siden av Terje Pedersen
Colon: Introduksjon
Jeg er en av disse særingene som synes det er gøy å leke seg med syntaks til eget programmeringsspråk og ikke bare måtte gjøre hva andre har funnet på og bestemt seg for.
Først holdt jeg på med et språk kalt Minky deretter ble det en ny iterasjon av Minky til jeg ble en smule fasinert av hvor lite kode en kunne klare seg med i det stack-baserte språket Raven. Så nå er det Colon det jobbes med.
Et av mine mål er å kunne skrive programvare kjappere for ARM-baserte duppeditter slik som OpenMoko-baserte Neo 1973 uten å måtte skrive en avhandling i kode, bare for noe så lite som en enkel GUI Hello World applikasjon.
Språket er kalt Colon rett og slett fordi en definerer ordene på samme måte som en gjør i et vanlig språk med kolon rett etter ordet.
- pi: 3.14
- hello: "Hello World" out
Videre brukes kolon til å hente ut et element fra stacken for så å lagre det i ordet som følger rett etter kolon.
- 5 10 4 :a :b :c
Bytte av innhold i to ord blir da:
- a b :a :b
Den tredje bruken av kolon i Colon er kolon som et ord på samme form som “Ternary” i C mao “cond ? expr1 : expr2”. Om en vil ha if/if istedenfor if/else brukes semikolon til avslutte. Ordene for å sammenligne som f.eks = > < osv. konsumerer bare det første elementet på stacken og dermed muliggjør også en switch type konstruksjon.
- 10 = ? "Number is equal to ten" out
- 10 < ? "Number is less than ten" out
- : "Number is greater than ten" out
Tall etter et ord er reservert som repitisjon av ordet x antall ganger og gjelder alle ord og ikke bare de som er definert som forskjellige ord som f.eks. dup2 og dup3 i andre stack-baserte språk. Omskrivningsregler av bytekode vil skrive om de vanlige slike dobble like bytekoder til egen der det er hensiktsmessig.
- 1 2 3 4 +3
- 10 dup4
Each = | og brukes for å ta ett og ett element til stacken og utføre det til høyre inntill kodeblokken er slutt eller til semikolon.
- {"cat" "dog" "horse"} | out
- 0 {1 2 3} | + ; out
- {} {1 2 a 3 4 b 5 6} | 3 > ? +
- {3 4 5} | ; # dytter tallene på stacken
- {{0 1} {2 3}} |2 ; :y :x "(@x,@y)" out
- {name: "Terje" age: 31} | key "key: @0 value: @1" out
- "file://test.txt" open lines | length "@0 chars in line @key" out
permalink |
kommentarer (0)




