I am trying to setup my RFM12Pi. When I run minicom 2.6.1, it hangs. I cannot press CTRL+A or anything. I must reboot. It hangs regardless of whether I have my RFM12Pi connected or not.
Also the LED on my RFM12Pi is solid, not blinking. I have my EmonTx shield running and it is blinking. I have set the appropriate frequency, node ID, and group name in my sketch.
I have tried killing my php process prior to running minicom, as suggested in the forum.
Thanks in advance for your help.
Re: Minicom not working
Turns out that minicom is not hanging. I am able to CTRL+A Z into the menu. But when I type "4b" to change frequency like the instructions say, nothing appears to happen.
Re: Minicom not working
Hi, Having a similar problem. I have two Raspberry Pi and following upgrade to "2012-12-16-wheezy-raspbian.img" over holidays both stopped working and minicom hangs (see attached image) not sure it is related as I have been making other changes also. You could try suggestions at http://openenergymonitor.org/emon/node/1311 - didn't resolve my issue.
Cheers
Peter
Re: Minicom not working
I got some very valuable information from Martin today about this!!
Regarding minicom, I suspect you have the PHP cron job that emoncms starts running in the background. you can't use both emoncms's cron and minicom at the same time, or you see gibberish; to stop the cron edit the crontab line and comment out the line that runs every minute and reboot.
Glyn and I have that same issue before, it was easily resolved by stopping the cron - the serial port can't be accessed both by emoncms and minicom at the same time.
I've added this to the wiki :-)!
Re: Minicom not working
Thanks that worked on both RPi's for me:
Access cron using
sudo nano /etc/crontab
then remove cron job by adding # to start of line below and reboot.
#*/1 * * * * root cd /var/www/emoncms/Modules/raspberrypi && php raspberrypi_ru$
Now you can use minicom and remember to reverse changes by removing # above and reboot.
cheers
peter
Re: Minicom not working
When I reboot RPi, it now stops updating remote URL. The Dashboard Raspberry Pi shows Cron job is running (green).
To rectify I login to dashboard Raspberry Pi and change remote url and save, then revert changes so url is correct and save again. Now posting to remote url.
I assume this is not normal behavior.
Cheers
Peter
Re: Minicom not working
Well done solving this. It seem that when an RFM12Pi system is ran for the first time (even using the pre-built SD card) cron needs to be killed then restarted. I have added instructions on how to do this to the 'ready-to-go SD card' part of the wiki, see step 12: http://wiki.openenergymonitor.org/index.php?title=Raspberry_Pi#Using_read-to-go_SD_card_image.
This is not ideal, the pre-built SD card needs to be as plug-n-play as possible for new users. Any ideas what could be causing this and how we could solve it?
Re: Minicom not working
Hi Glyn,
Thanks for reply. I hope the following doesn't add to confusion but here goes. I used 2012-12-16-wheezy-raspbian.img and followed your very clear instruction.
Basically it works fine with ethernet plugged into my broadband router. I have power cycled several times with no issues e.g. it comes straight back and will post to remote URL within a few seconds. However I did # out cron job to look at rfm12b using minicom which may have helped (similar to step 12 above??).
The problem I'm experiencing seems only related to 3G dongle (both K3765 & K3520). Sequence - Unplug ethernet from broadband router and connect 3G dongle then power cycle RPi. Outcome - it comes back but doesn't post to remote URL (Note that www is available and I can google ok at this stage). Note Cron is running and green at the stage. Next I implement sequence mentioned in above post "To rectify "I login to dashboard Raspberry Pi and change remote url and save, then revert changes so url is correct and save again". Outcome it immediately starts updating remote URL.
FYI I am using Zoo133 implementation of sakis3g which can be found at http://zool33.uni-graz.at/petz/umtskeeper/. I've being trying to get 3G working for a while with mixed results, the NanodeRF with TP-Link W703n ( only 16€) flashed with openwrt looked very promising but when RPi became available I was smitten. I'm at early stage with RPI 3G but will share experience as testing progresses, the 3G connection has been stable for a few days now on two RPi's except when I have deliberately power cycle then I lose remote URL update.
Cheers
Peter
P.S. Is there some way I could check cron activity or log events in both scenarios to narrow issue somewhat? I noted cron jobs running after boot with 3G dongle (remote URL not updating) and then after sequence above to get it updating - the Cron jobs running are same before and after. I will test more scenarios over coming days and if I find anything interesting will post same. A bit ahead of myself as I'm not a programmer but found this link for starting stopping Cron. http://stackoverflow.com/questions/6548746/how-to-start-stop-a-cronjob-u...
Re: Minicom not working
Hi. Fresh install using read-to-go SD card image and followed your instructions for same (except 12). Note I first tried sequence I used to get posting to remote URL above but it had no effect. Rebooted and followed instruction 12 and raspberry pi cron starts running and posting to remote URL as one would expect.
From above it would seem like while issues are similar they're not the same, I will add 3G parts tonight to compare what happens, when I follow step 12. It will be interesting to see it this fixs my 3G issue.
Cheers
Peter
P.S Hadn't used ready to go SD before, worked great thanks ( ethernet to home router). The ready to go SD is excellent and will save hours.
Re: Minicom not working
3G dongle working but won't post to to remote URL after reboot. The 3G connection comes up and I can browse internet, raspberry pi cron shows still running. Tried a number of fixs including restart of cron - raspberrypi_run.php. "To rectify the process used "I have to login to dashboard Raspberry Pi and change remote url to false URL and save, then revert changes so url is correct and save again".
This process obviously resets something for remote URL and API somewhere, or restores some missing data but I don't know what. Anyone shed some light on what above process may do or what may be restored or reset during process it may help with fix e.g. cron job rather then manual process.
Cheers
Peter
P.S. started new thread http://openenergymonitor.org/emon/node/1903
Re: Minicom not working
Still stuck! Cron has been commented out, as per the new instructions.
First attached image is what I see when I load minicom.
Second attached image is what I see when I unplug and replug my RFM12Pi.
Is this normal behavior? My Tx shield is up and running (blinking), but I see no data on minicom screen. Typing "4b" for 433MHz also seems to have no effect.
Re: Minicom not working
You need to reboot for comment out to take effect.
I thought RFM12B was 868Mhz which would need 8b
Using ready-to-go SD also I have commented out cron as discussed and then reboot RPi
I now get see attached see instructions below.
minicom -b 9600 -o -D /dev/ttyAMA0
then t
Don't forget to uncomment crontab when your finished and reboot.
Good Luck
Cheers
peter
Re: Minicom not working
Yes, I have rebooted after commenting out the cron line.
Still nothing in my minicom window. I do not see your list of Available Commands on my screen.
Why have you typed "t"? I have tried this and nothing happens.
Re: Minicom not working
Looking at the screenshot you sent before, it appears that the ATTiny isn't talking to the RFM12b module - a help message should appear after initialization, not just the program name.
Can you post close up picture of your RFM2Pi board ?
Also - there is no 't' command in this version of the software, any unrecognized command just shows the help message
Re: Minicom not working
Thanks for clarifying, not sure why I started, I just noticed that when I logged into minicom and typed t I got summary of commands and also configuration. Correct it works for any key.
cheers
Peter
Re: Minicom not working
Here is the image of the board.
I have verified continuity of the Pi header pins to the board. Thanks for your help in diagnosing!
Re: Minicom not working
Just a thought: is it possible the microcontroller on the board did not come flashed with firmware? I did purchase through the OpenEnergy store.
Re: Minicom not working
Your soldering is excellent - the board looks great.
The microcontroller must be programmed as it outputs '[RFMDemo.Attiny84]' to the serial;
Do you own an ISP programmer? Maybe you can try to set the fuses to 8Mhz if by chance they weren't set and re-flash with the latest firmware. If that's hard for you, I suggest contacting Glyn or Trystan for a replacement
Re: Minicom not working
Thanks for your help. Glyn is kindly sending me a new ATtiny.


Introduction to HTML
As you learned in the Intro to Web, HTML is everything on the page you can
see, including headings, paragraphs, images, or buttons.There are actually a lot of similarities between a HTML page and a google doc. Just like in a google doc, HTML allows you to add elements to the page like text, buttons, headings, paragraphs, links, and photos.The big difference between the two is in
how you do it. In google docs, to add a picture to your page you click "insert" and then "image" and then you upload a picture from your computer. In HTML, instead of clicking to add a photo you have to use the html tag for photo by typing it using HTML code.Similarly, if you want to make a Heading in google docs, you highlight the text you want for the heading and click "Normal text" and then switch it to "Heading 1." In HTML, you have to use the HTML tag for Heading 1 by typing it onto the page in HTML code.So now you are beginning to get what HTML can do... but how do you do it?Writing HTML codeWriting an HTML tag is kind of like making a sandwich. That sounds pretty weird, but bear with me. There are three main things you need for a sandwich:
- Top piece of bread
- Yummy stuff in the middle
- Bottom piece of bread
You need the same things in HTML! But instead of food, you'll need:
- An open tag
- Content to go in the middle
- A close tag
HTML is made of lots of different tags. You combine tags to make a webpage. Different kinds of tags include text, headings, images, buttons, etc. To put a tag on your page, you'll need to start with an open tag.
(That's the top layer of bread.) Each tag has a specific letter/name, which is represented by the letter between the < and >. The element for normal text is a p tag, and so its open tag it looks like this:
.
The close tag that matches
 is
. (Notice how the open and close tag are different? The close tag has a / right after the first <.)A full p-tag looks like this:

Okay.  To start, you're going to need to go to jsbin.com and make an account if you don't have one. After you've created an account: 1) Copy and paste the above p-tag into JSBin between the
 and  tags.
What do you see in the output? Nothing, right? That's because we have the p-tag on the page, but it's empty. (It's a bread sandwich -- there's nothing inside to make it interesting!)
The
words that you want to write on the page go between the open and close tag:

This is a p tag.

2) Go back to JS bin and add text to your
 tag.
Most
other elements will work the same way as the
 tag. For example, if you want to make a button that says click me, the code will look like this:
<button>Click Me!</button>
3) Try making a button in JsBin! (Clicking the button won't do anything yet. We'll work on that once we're using JavaScript.)
If
you want to make a heading for your page with your name, it will look like this:

Your Name

You notice that in every example, there is the open tag, close tag, and content in the middle, right? Great. Let's
look at this picture of HTML code:
Does it make a little more sense now?
Now that you've mastered the format let's move on to attributes,
which will allow you to provide more specific information about an element.
Attributes
So, we're going to stop talking about sandwiches now.
Let's pretend that a single HTML tag is like a person.
Attributes are just ways to describe the person in more detail,
like their name, their hair color, their eye color, etc.
Attributes provide additional information about an element.
They must be written in the open tag. Attributes are formatted like this: attribute="value".
So if your name was Jake, we could use name="Jake" as an attribute to describe you.
One attribute that you'll use a lot is the id attribute.
It allows you to give your element a name that can be used to identify it in CSS and JavaScript.
So if you were an HTML element named Jake, we'd actually say id="Jake" because id's are the names of HTML elements.
This is a p tag with an id of elementName:

To have an image on your page, you'll need to use an  tag.
To specify which picture shows up, use the src attribute (src stands for source of the image.)
To choose a picture, choose an image in google images right-click it and copy the photo's address.
Paste that address as the image's source as we do below:

-
Copy and paste the above img tag into JSBin.
-
Can you find an image on google (using the instructions above) and put it onto your page below this image?
There are hundreds of different attributes.
Some attributes only work with specific elements, like src.
Some, like id, work for all elements.


Use the lists to select a color.
Basic List
Red
Green
Coral
MediumOrchid
Different List Sizes
With borders to demonstrate container size
Available Sizes: auto, x-small, small, medium, large, x-large
List Width: {{size}}
Red
Green
Coral
MediumOrchid
Minimum Width
With borders to demonstrate container width
Min Width: x-small
Red
Green
Coral
MediumOrchid
Navigate Focus via Keyboard
Use <tab> to focus an item in the list, then use up/down and
left/right keys to navigate.
Red
Green
Coral
MediumOrchid
Primary and Secondary Item Content
Item with secondary
ctrl+x
Item with primary icon
Item
Item
Grouping and Dividers
Item
Item
Item with secondary
ctrl+x
Small Group Item
Item with primary icon
Item
Item


RequestDispatcher: include of Dump servlet. RequestDispatcher: include static file. RequestDispatcher: include of named Dump servlet. RequestDispatcher: include snoop.jsp. CGI Servlet: Unix only demo of cgi-bin servlet.


Correcting area under ROC (AUC) for measurement error based on probit-shift model.
| Version: | 0.0.3 |
| Depends: | R (≥ 3.1.0), stats |
| Imports: | ICC, mnormt |
| Published: | 2016-06-29 |
| Author: | Bernard Rosner, Shelley Tworoger, Weiliang Qiu |
| Maintainer: | Weiliang Qiu <stwxq at channing.harvard.edu> |
| License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| NeedsCompilation: | no |
| Materials: | NEWS |
| CRAN checks: | correctedAUC results |
| Reference manual: | correctedAUC.pdf |
| Package source: | correctedAUC_0.0.3.tar.gz |
| Windows binaries: | r-devel: correctedAUC_0.0.3.zip, r-release: correctedAUC_0.0.3.zip, r-oldrel: correctedAUC_0.0.3.zip |
| OS X binaries: | r-release: correctedAUC_0.0.3.tgz, r-oldrel: correctedAUC_0.0.3.tgz |
Please use the canonical form https://CRAN.R-project.org/package=correctedAUC to link to this page.


Part 1 - Scheme Basics¶
Basic syntax¶
Scheme syntax is very simple: everything in the language is done with s-expressions. (sexp’s for short.) A simple s-expression is either one atom (such as a symbol, number, string), or a series of atoms surrounded by parentheses. S-expressions can be nested to any depth we want.
When we send an sexp to the interpreter to be evaluated, the interpreter evaluates all nested expressions, from the inside out, ending with evaluation of the outer sexpr. Evaluation of a parenthetical s-expr is done by calling the first atom as a function, with the remaining atoms passed as parameters, also called arguments. (In strict computer science circles, there are differences between the terms “procedure” and “function”, and between “parameter” and “argument”, but we are not going to worry about those here, you can take them as synonyms for now.)
; evaluating an sexp that calls the function bound to the symbol '+'
; evaluating this sexp calls the function with arguments and returns value 2
(+ 1 1)
s4m> 2
; post is a function, and we can pass nested sexprs to it
; post returns null, but prints as side effect
(post "1 + 1 is:" (+ 1 1))
s4m: 1 + 1 is: 2
s4m> ()
This syntax is called prefix notation - functions are in the first slot, followed by as many arguments as the function will permit.
; add more numbers!
(+ 1 2 3 4)
s4m> 10
Nesting is simple - just add more sexps. They are evaluated from the inside out.
;; a compound expression
(+ 1 (* 2 (+ 3 4)))
s4m> 15
In the above, three sexps get evaluated. First, (+ 3 4) evaluates to 7 by calling the + function with arguments 3 and 4, resulting in (+ 1 (* 2 7))). Next, (* 2 7) is evaluated by calling the * function with arguments 2 and 7, leaving (+ 1 14). Finally, the remaining sexp is evaluated by calling the + function with arguments 1 and 14. Each round of evaluation calls a function, replacing the sexp with the results.
This is critical to understand. Evaluation of an sexp calls the function (or special form) in the first slot, with the arguments from the rest of the sexp, and nested sexps are evaluated inside-out.
Variables¶
The define function creates a variable by binding a value to a symbol in the currently executing scope. If we run define at the top level of our program, this will be the global scope and this binding will be visible everywhere in our program. (Unless it is shadowed by another binding of the same symbol, which we will get to later…)
; define a variable by binding the symbol 'a' to the value 99
(define a 99)
s4m> 99
This function has a side-effect, meaning it does something other than just return a value. Its side effect is binding the variable. In s7 (but not all Schemes), define also returns the value that was bound. Which means we could, if we really wanted, do something like this:
; both b and a will be bound to 99
; not recommended, here for illustration only!
(define b (define a 99))
s4m> 99
Evaluation does not always mean calling a function. If we evaluate a form that is not a function call, we get something back, with what that something is depending on the form. Evaluating a basic type returns the value itself (no change) and evaluating a variable returns the value bound in the variable.
; evaluating a simple type like a number returns the value
99
s4m> 99
(define foo 99)
s4m> 99
; evaluating a variable returns the value bound to the variable
foo
s4m> 99
Once a variable has been created, we can assign a new value to it with the set! function. It’s a common Scheme convention to name functions with side-effects with a trailing exclamation mark. In s7, set! also returns the value set. We can only set a variable that has already been defined. In s7 (but not all Schemes), we can also set a new value on an existing variable by just redefining.
(define a 99)
s4m> 99
a
s4m> 99
(set! a 100)
s4m> 100
a
s4m> 100
(define a 101)
s4m> 101
a
s4m> 101
(set! z 999)
s4m> ERROR unbound variable z
Functions¶
Functions are defined using the special form lambda. Evaluating a lambda form will return an anonymous function, which we can in turn bind to a variable.
The lambda form takes two clauses: a parameter list and a body. The parameter list specifies the local bindings that will be active in the body of the function, based on the arguments passed in. The body gets evaluated when we call the function, with whatever arguments are passed in at call time substituted for the parameters.
; a lambda expression that takes an argument, x, and returns x + 1
; it returns a lambda procedure
(lambda (x) (+ 1 x))
s4m> #<lambda (x)>
; the same, but binding the function to the symbol my-fun
(define my-fun (lambda (x) (+ 1 x)))
s4m> my-fun
; now call the function
(my-fun 2)
s4m> 3
; this means we could just nest the lambda form in order to call it
; but this is not very readable, so less commonly done
((lambda (x) (+ 1 x)) 3)
s4m> 4
; a lambda form specifying a procedure with two parameters
(define my-adder (lambda (a b) (+ a b)))
s4m> my-adder
(my-adder 3 4)
s4m> 7
There is a shortcut in Scheme, (sometimes called “defun” notation, from Common Lisp), that allows us to define functions without explictly using lambda. Under the hood, it’s exactly the same.
; define a function called add-1, that adds 1 to its argument
(define (add-1 x) (+ 1 x))
s4m> add-1
; this is no different from the below
(define add-1 (lambda (x) (+ 1 x)))
; in S7 we could do this, because define returns the value bound
; again, not recommended, but a useful illustration
((define (add-1 x) (+ 1 x)) 2)
s4m> 3
Some texts only use the lambda form as it is more explicit, and thus clear what is going on. We will use both as space can be at a premium in a Max patch!
Output in Scheme For Max¶
In Scheme for Max, we have two functions we will use all the time for output, out and post. out is used to send values out the s4m object’s outlets. It takes two arguments, the outlet number, and the value to be sent out. In Scheme For Max, we call the first outlet “outlet 0”.
out is an example of a function that is called purely for its side-effect - output a number. We send output out a lot, so we don’t necessarily want to see every value sent out showing up in the Max console. For this reason, out returns null. This way, if our Scheme for Max object’s log-null attribute is false (the default), we will not see any console activity on a call to out.
In Scheme, null is technically the null list, and it’s printed representation is (). We will explain why later on. For now, just know this is null, and it means “empty value”.
; send the number 99 out the first outlet
; this function also returns the null list
(out 0 99)
; pretend we set @log-null to 1
(out 0 99)
s4m> ()
From now on, the tutorial will not always show the returned null value, such as after calls to post, as it does clutter up examples.
If we want so send out multiple values, so that the output is a Max list message, we use the list function:
; send the list 1 2 3 out the first outlet
; the list function returns a list
(out 0 (list 1 2 3))
The post function logs to the Max console. It accepts any number of arguments, automatically converting them to string representations and putting spaces between them. It is also being called for its side effect and so returns null. You’ll see that the prompt from post printed output is s4m: instead of the repl return prompt of s4m>
; post to console, with log-nulls set to true
(post 1 2 3)
s4m: 1 2 3
s4m> ()
; post a variable
(define a 99)
s4m> 99
(post "a is" a)
s4m: a is 99
s4m> ()
During development, it can be helpful to attach a print s4m-out: object to your outlet, giving you all the output in your Max console while you work.
; shows return value (if @log-nulls is 1) and the printed output from our print object
(out 0 :foobar)
s4m> ()
s4m-out: :foobar
Basic types¶
Scheme is dynamically typed, meaning that we do not have to specify in advance of what type a variable will be, but variables do have types.
Booleans and Predicates¶
In Scheme, we use #true and #false for boolean values, which can also be written as #t and #f. A predicate function is a function that checks the value of an expression against some criterion and returns a boolean. In Scheme, predicate functions normally have names ending in a question mark.
; make a boolean variable
(define my-boolean #t)
s4m> #t
; check if it is a boolean
(boolean? my-boolean)
s4m> #t
Some other useful predicates:
; check if a variable is a function/procedure with procedure?
(procedure? post)
s4m> #t
; the defined? predicate checks if a symbol is a defined variable
(defined? foo)
s4m> #f
(define foo 1)
s4m> 1
(defined? foo)
s4m> #t
We can check whether something is null with the null? predicate.
; the out function returns null, so...
(null? (out 0 99))
s4m> #t
As an aside, remember that null is actually the null list, meaning that using the list? predicate on the return value will also be true:
; the out function returns null, and null is the null list, so...
(list? (out 0 99))
s4m> #t
; just for fun...
(boolean? (list? (out 0 99)))
s4m> #t
Numerical Types¶
Like most programming languages, Scheme supports integers and floats, but in Scheme, both are sub-types of the number type. In Scheme, floats are inexact numbers, while integers are exact numbers. Unlike many other languages, Schemes also support fractions as a type, which is very helpful in music. There are number of predicate functions and conversion functions for working with numeric types, and there are some rules for automatic conversion you will want to know. The examples below provide enough to work with in Max, and for further details you can consult various online resources.
; make an integer
(define x 1)
s4m> 1
(integer? x)
s4m> #t
(define y 2.0)
s4m> 2.0
; y is not an integer
(integer? y)
s4m> #f
; y is an inexact number
(inexact? y)
s4m> #t
; but both x and y are numbers, and real numbers
(and (number? x) (number? y)
s4m> #t
(and (real? x) (real? y))
s4m> #t
; mixing inexacts and exacts creates other inexacts
(/ 1 0.5)
s4m> 2.0
; integer math creates fractions
(define z (/ 3 4))
s4m> 3/4
; these are still exact
(exact? z)
s4m> #t
; which we can later cast to inexact
(exact->inexact (/ 3 4))
s4m> 0.75
; exacts stay exact until mixed with inexact
(* 1.0 (/ 3 4))
s4m> 0.75
Because of the support for fractions, we can stay exact through a chain of operations, only converting at the end, a vastly preferable situation for converting tuning or timing fractions compared to languages like JavaScript or C. This does mean that we need to be more explicit in coversions however, and so there are some helpers in the form of floor, ceiling, and round.
(floor 1.1)
s4m> 1.0
(ceiling 1.1)
s4m> 2.0
(round 1.5)
s4m> 1.0
(round 1.51)
s4m> 2.0
Symbols¶
Symbols are identifiers in Scheme that can be used as the name for functions and variables. They can hold more characters than in most languages, because Lisps only use whitespace and parentheses for syntax. In Scheme, it’s common to include hyphens, exclamation marks, and questions marks in names.
; symbols for predicates usually end in question marks
(define is-one? (lambda (x) (= 1 x)))
Evaluating a symbol returns the value stored at that symbol:
(define answer 42)
sm4> 42
answer
s4m> 42
Strings and characters¶
Scheme also has a string type and a character type. Now strictly speaking, Max doesn’t really do strings - to Max they are just symbols with quotation marks. So we won’t discuss either of these in much detail, especially characters. A good rule of thumb in Max is to avoid strings unless you need a string. In Scheme, Strings use double quotes.
(define foo "foo")
s4m> "foo"
(define bar "bar")
s4m> "bar"
; join strings with string-append
(string-append foo bar)
"foobar"
s7 includes a variety of string conversion routines, which one can look up in the online Scheme references (Dybvig is my recommendation). Some of the more useful ones are:
(number->string 1)
s4m> "1"
(string->number "1")
s4m> 1
; note that string->number and number to string are smart about floats
(string->number "1.0")
s4m> 1.0
; and even fractions!
(string->number "3/4")
s4m> 3/4
; of course, there's a predicate...
(string? (number->string 1))
s4m> #t
We can also go back and forth between symbols and strings.
; make a symbol from a string
(symbol "foo")
s4m> foo
; and its predicate
(symbol? (symbol "foo"))
s4m> #t
; round and around
(string? (symbol->string (symbol "foo")))
s4m> #t
There are also functions for extracting characters from strings and building up strings, but I don’t find myself using these much in Max, so we’ll leave this to the reader to explore online. That’s all we’ll say about strings in this crash course.
Lists - an introduction¶
Lists are the most important compound data type in Lisps, including Scheme. So much so that Lisp originally stood for “List Processing”! We’ll be looking at lists in detail later, but right now we have a bit of a chicken-and-egg situation: we need to know at least a little bit about them for the next section to make sense.
We make a list using the list function:
; make a list
(list 1 2 3)
s4m> (1 2 3)
; store a list in a variable
(define l (list 1 2 3))
s4m> (1 2 3)
We can retrieve individual members of a list by index using list-ref, and we can set them using list-set!:
; get value of l at index 0
(list-ref l 0)
s4m> 1
; set value of l at index 0
(list-set! l 0 99)
s4m> 99
; eval the variable, and we get the (updated) list
l
s4m> (99 2 3)
In s7, we can also use what is called applicative-syntax, where we use a list in the function slot of a paranthetical expression, and put the index in the argument slot. Note that the syntax for set is a bit unusual, we use the syntax for getting an item to refer to a location, and the location is the argument to set!.
; get value of l at index 0, applicatively
(l 0)
s4m> 1
; set using applicative syntax
(set! (l 0) 100)
s4m> 100
l
s4m> (100 2 3)
Lists look at first like an array in other languages, but under the hood, lists in Lisp are actually implemented as linked lists. There is a whole family of functions for working with lists as linked-lists, and we’ll get to those soon.
The astute reader will have noticed that the printed representation we get back when evaluating a variable that holds a list (or a call to the list function), looks an awful lot like an s-expression. In the above example, it looks just like a call to a function called “100”. Hold that thought, it’s going to become very important!
Evaluation and quoting¶
At this point, we are able to make variables and functions, and we know about basic types and lists. It’s time for our first look at what make the Lisp family of languages unusual.
When we send an s-expression or atom to the interpreter to run, we are asking the interpreter to evaluate the expression. We can also do this explicitly using the eval function. In the case of a basic number or string, evaluation doesn’t change anything - it returns the same value:
; send a number to the interpreter, and we get the same thing back
99
s4m> 99
; as evaluating doesn't change it, the eval function won't either
(eval 99)
s4m> 99)
; thus nesting evals of a number doesn't either
(eval (eval 99))
s4m> 99
; strings also evaluate to themselves
(eval "foobar")
s4m> "foobar"
However, when we evaluate a symbol, the evaluation process returns that which the symbol points to. Which of course requires that either this symbol is either bound in the language, or that we have by bound it ourselves by defining using the symbol. The value pointed to could be an atomic data item, in the case of a variable, or a function, in the case of a function name:
(define my-var 99)
s4m> 99
my-var
s4m> 99
(eval my-var)
s4m> 99
(define (add-1 x) (+ 1 x))
s4m> add-1
; evaluating the symbol that points to the function returns the function
add-1
s4m> add-1
(eval add-1)
s4m> add-1
But what if we evaluate a list? Hang on to your hats!
; evaluate a list
(eval (list 1 2 3))
s4m> Error; attempt to apply an integer 1 to (2 3) in (1 2 3)?
We get an error message about “applying an integer”, giving us a clue what’s going on. Let’s try that again, but instead of the just using the list function, we will add the use of the symbol function, which we recall creates a symbol from a string:
; make the symbol post, from a string
(symbol "post")
s4m> post
; make a list, starting with the symbol
(list (symbol "post") 1 2 3)
s4m> (post 1 2 3)
; evaluate this list, and we see we have called the post function
(eval (list (symbol "post") 1 2 3))
s4m: 1 2 3
s4m> ()
; or more concisely ...
(eval (list post 1 2 3))
s4m: 1 2 3
s4m> ()
Now we can see what is going on. Evaluating a list is the same as calling a function. Literally the same. The first element of the list is taken as indicating a function, and the rest are its arguments. Scheme syntax consists of lists. We can build them with functions or special forms, and we can call them as functions with eval.
Eval has a counterpart that does the opposite: quote. When we use quote, we tell the interpreter to skip evaluation of something that it would otherwise evaluate. In a normal function call, expressions used as arguments are evaluated prior to the function call, and the values returned are passed to the function as arguments. For example:
; define a function that prints its argument
(define (my-post x) (post "in my-post, x is:" x))
s4m> my-post
; my-post gets passed the value returned by evaluating (+ 1 2)
(my-post (+ 1 2))
s4m: in my-post, x is: 3
s4m> ()
If we use quote, we tell the interpreter not to evaluate the expression and use the result as x, but rather to pass the expression itself, as code, in as a argument:
(my-post (quote (+ 1 2)))
s4m: in my-post, x is: (+ 1 2)
s4m> ()
This is used so frequently in Lisps that is has a special shortcut syntax, the single quote character:
(my-post '(+ 1 2) )
s4m: in my-post, x is: (+ 1 2)
s4m> ()
When we use the single-quote, it indicates that the rest of the immediately following s-expression should be used as it is written in code, not as it would evaluate. If we use it in front of a parenthetical expression, it thus returns a list, instead of calling a function:
; this returns the result of calling + with the args 1 and 2
(+ 1 2)
s4m> 3
; whereas this returns a list, the first element of which is +
'(+ 1 2)
s4m> (+ 1 2)
This means quote is also a shortcut for making lists:
(define l '(+ 1 2 3))
s4m> (+ 1 2 3)
l
s4m> (+ 1 2 3)
; now call that list as a function
(eval l)
s4m> 6
We can also use quote in front of a symbol to indicate that we want the symbol, not the value at which the symbol points. This will work even if the symbol has not been used to define a variable.
; make a list of symbols a b c
(list 'a 'b 'c)
s4m> (a b c)
; which is precisely equivalent to quoting the whole expression
'(list a b c)
s4m> (a b c)
; we could evaluate this, which will work if a b c are defined
; and a is function, but be an error if they are undefined
(eval '(a b c))
s4m> Error: unbound variable a in (a b c)
; an example that works
(define foo 99)
(eval '(post foo))
s4m: 99
s4m> ()
Quote and eval are opposites, so we can nest them as much as we want:
(eval '(post "hello world"))
s4m> hello world
(eval (quote (eval '(post "hello world"))))
s4m> hello world
Keywords¶
Some Lisp dialects, including s7, have keywords. A keyword is a symbol that starts with a colon and always evaluates to itself. A keyword can not be bound to anything other than itself - it can’t be the name of a variable or function. In this way, it acts like a simple type, such as a string or number. This also means a variable can hold a keyword, but a keyword can’t be a variable.
When we get to hash-tables and dictionaries, you’ll see that keywords are commonly used as keys. Conveniently, Max will let us use them in many places as well, including table and dict names.
; evaluating a keyword has no change
; much like evaluating a simple type
:my-keyword
s4m> :my-keyword
(define var-holding-a-keyword :my-keyword)
s4m> :my-keyword
(eval var-holding-a-keyword)
s4m> :my-keyword
; but no using them as variable names!
(define :my-keyword 99)
s4m> Error: keywords are constants
We will use quoting and evaluation a lot in Max, so keywords are very helpful. We can see at a glance that a symbol starting with a colon is a keyword, no matter the context. It doesn’t matter if we’re not sure whether it will get evaluated, because evaluation won’t change anything.
Lists, in more depth¶
As we previously discussed, under the hood, Lips lists are linked-lists. In the computer memory, every cell in a list includes a value, and a pointer to the next item. The last item in a list has a pointer to a hidden cell that holds the null list. So if we look at a list of three elements, ‘(1 2 3), there are three cells with numbers and pointers, and one hidden cell with the null list, to which the third cell’s pointer points. Or another way of thinking of it is that there are three cells, the last of which points to the null list, which is a special case.
In this section we will look briefly at the classical Lisp list functions. I will admit these Lisp list functions have bizarre names: car, cdr, cons, etc. While these names seem annoying at first, they have stuck around as they are easy to type, and will become second nature pretty quickly. (They originally come from operating instruction names on very old IBM computers!)
We can get the first item of a list using the car function, and we can get the rest of the list, by using the cdr function. We can think of the combination of car and cdr as taking off the head of the list, which leaves us with one single item (the car) and the remaining linked list (the cdr). Thus cdr, if called on a proper list, always returns a list. Though the list it returns could be the null list, if the head was the last proper item. An example is worth a thousand words here:
; a list
(define l (list 1 2 3))
s4m> (1 2 3)
; get the car of l
(car l)
s4m> 1
; get the cdr of l, it's always a list
(cdr l)
s4m> (2 3)
Because cdr returns a list, we can get the cdr of a cdr - this is like chopping off the head twice - and we still get a list:
; get the cdr of cdr of l
(cdr (cdr l))
s4m> (3)
; note the above is a *list* with 3, not 3 itself!
; the very last cdr is the null list
(cdr (cdr (cdr l)))
s4m> ()
; which can be checked with the null? predicate
(null? (cdr (cdr (cdr l))))
s4m> #t
; but is also still a list!
(list? (cdr (cdr (cdr l))))
s4m> #t
So it’s important to remember that a proper list is a set of value/pointer entries, where the last one points to the null list. The value-pointer pairs have a special name: cons cells.
In addition to making lists with the list function, we can use the cons function. The list function does the magic for us, while cons involves us in the underlying linked-list. We use cons to add a new cons cell by passing in an item, and a list that our new cell should link to.
; extend our list at the front
(cons 0 (list 1 2 3))
s4m> (0 1 2 3)
Note that cons makes a new list. This is an important distinction. Making a new list by adding a cell to the head doesn’t change an old list starting at a different head:
(define list-a (1 2 3))
s4m> (1 2 3)
(define list-b (cons 0 list-a))
s4m> (0 1 2 3)
list-a
s4m> (1 2 3)
list-b
s4m> (0 1 2 3)
In the above example, the cdr of list-b is list-a.
To make a list from scratch with cons, we must backwards, starting with the null list. And we make the null list by quoting the printed representation of an empty list, ‘().
(null? '())
s4m> #t
; make a list by cons'ing to the null list
(cons 3 '())
s4m> (3)
; make a list by cons'ing 3 times
(cons 1 (cons 2 (cons 3 '())))
s4m> (1 2 3)
If we want to add to the end of a list, we need to use the append function, which takes multiple lists as arguments returns a new list consisting of the joined argument lists. This means that, unlike cons, the item to be added needs to itself be a list. Like cons, the result is a new list, and the original lists are unchanged.
; make a list, by joining two lists
(append (list 1 2 3) (list 4 5 6))
s4m> (1 2 3 4 5 6)
; add one item to a list
(define l (list 1 2 3)
s4m> (1 2 3)
(append l (list 4))
s4m> (1 2 3 4)
; note that l is unchanged!
l
s4m> (1 2 3)
; or with quote
(append l '(5))
s4m> (1 2 3 4 5)
Append can have as many arguments as you want
(append (list 1 2) (list 3 4) (list 5 6))
s4m> (1 2 3 4 5 6)
Note that if you call append with a final element that is not a list, you won’t get an error… but you also won’t get a proper list. This is because the final item is an atomic value instead of a value/pointer pair.
(append (list 1 2) 3)
s4m> (1 2 . 4)
The dot before 4 indicates that the list stopped being a proper list at the third item. Improper lists are used in various places, but most typically as pairs, also called dotted pairs. We get them when we use cons, without ending our chain with the null list:
; consing to an atomic value produces a dotted pair
(define my-pair (cons 1 2))
s4m> (1 . 2)
Under the hood, a dotted pair consists of two cells: the first has a value and a pointer to the next cell, and the second has only a value. This means we can use car and cdr, but there is no cdr of the second element.
; consing to an atomic value produces a dotted pair
(define my-pair (cons 1 2))
s4m> (1 . 2)
(car my-pair)
s4m> 1
(cdr my-pair)
s4m> 2
(cdr (cdr my-pair))
s4m> Error: cdr argument 2 is an integer, but should be a pair.
Dotted-pairs and improper lists are important to understand as you’ll use them when looping through data structures such as association lists and hash-tables, both of which have pairs of key and value.
List accessor shortcuts¶
Finally, and these gets almost silly but are convenient, there are shortcuts for combinations of car and cdr that are useful when working with nested lists. These can always be replaced by nested combinations of car and cdr, so you don’t need to know them. But you are quite likely to see them in other lisp code, so it’s worth knowing they exist, and they can make some code more readable (or at least, to someone who knows these oddball functions!).
; car of nested list
(car (list (list 0 1) (list 2 3) (list 4 5)))
s4m> (0 1)
; cdr of nested list
(cdr (list (list 0 1) (list 2 3) (list 4 5)))
s4m> ((2 3) (4 5))
; caar gets the car of the car
(caar (list (list 0 1) (list 2 3) (list 4 5)))
s4m> 0
; cdar gets the cdr, of the car - which is a list
(cdar (list (list 0 1) (list 2 3) (list 4 5)))
s4m> (1)
; cadr gets the car, of the cdr
; aka the first item of the cdr of the outer list
(cadr (list (list 0 1) (list 2 3) (list 4 5)))
s4m> (2 3)
; cddr gets the cdr of the cdr, which is a list of lists
(cddr (list (list 0 1) (list 2 3) (list 4 5)))
s4m> ((4 5))
This continues on to 5 letter combinations, like cadar, and honestly, you don’t need to know these. But as you may well encounter code with functions consisting of strings of c,a,d, and r, know you’ll know what you’re seeing.
Optional function arguments¶
Know that we know about lists, we can use them for creating functions that can be called with a variable number of arguments. (Also known as “multi-arity functions” if you want to talk fancy computer science lingo!) This is done by using dotted notation in the function argument, which will put any arguments past the explicitly named arguments into a list. This list will be the null list if no additional arguments are given:
; one mandatory argument x, and 0 or more optionals
; the list 'args'
(define (my-fun x . args)
(post "called with" (length args) "optional args")
(post "optional args:" args))
s4m> my-fun
(my-fun 1)
s4m: called with 0 optional args
s4m: optional args: ()
s4m> '()
(my-fun 1 2 3)
s4m: called with 2 optional args
s4m: optional args: (2 3)
s4m> '()
This can be done with lambda as well, but lambda has an additional option. If the argument list for a lambda is only one symbol, this symbol will be bound to a list of all the arguments.
; a lambda that bundles all its args into a list
(define my-lambda (lambda args (post "args:" args)))
s4m> my-lambda
(my-lambda 1 2 3)
s4m: args: (1 2 3)
s4m> '()
s7 Scheme borrows heavily from Common Lisp, and includes two non-standard special forms, define* and lambda*, that give us the ability to use keyword arguments with default values in our function definitions. We do this by using lists of key and default value in place of arguments. To call the function with a keyword argument, we pass in a keyword and a value pair for that argument. This is most easily explained with the example below, taken straight from the s7 documentation:
; a function with one required argument, a, and two optional
; keyword args, b & c, with default values of 32 and "hi"
(define* (hi a (b 32) (c "hi"))
; returns a list of the arguments
(list a b c))
s4m> hi
; call hi with only one argument and we get the defaults
(hi 99)
s4m> (99 32 "hi")
; call hi with three arguments, and we use them all
(hi 99 88 77)
s4m> (99 88 77)
; call hi with one argument and one keyword argument
(hi 99 :c 77)
s4m> (99 32 77)
Vectors¶
Lists do have some disadvantages. Linked lists need to be traversed to get to their contents, which means that accessing elements deep in a long list can be slow. And adding items to the end of a list requires copying the entire list with append. In music situations, we often need to access anywhere in a sequential data structure, or add items at the end of a table, so for these types of cases, a more appropriate type is the vector. Like lists, vectors can hold any data type, and can hold multiple data types within a vector. If we want to model Max data that would be in a buffer or table in Max, the vector is likely what we want.
Note that the printed representation of a vector starts with # to differentiate it from a list.
; create a vector, containing 1 2 3 4
(define v (vector 10 11 12 13))
s4m> #(10 11 12 13)
; get its length
(vector-length v)
s4m> 4
; is it really a vector?
(vector? v)
s4m> #t
; access an element
(vector-ref v 2)
s4m> 12
; or with applicative syntax
(v 0)
s4m> 10
; set with vector-set!
(vector-set! v 0 99)
s4m> 99
v
s4m> (99 11 12 13)
; or with applicative syntax
(set! (v 0) 100)
s4m> 100
; make a vector using quote and the # sign
(define v '#(0 1 2 3))
s4m> #(0 1 2 3)
Note that Max only has a list type for messages, so when we cross the Max to Scheme boundary and vice versa, it’s worth thinking about which type is appropriate. Vectors can be converted to and from lists easily, and S4M will use vectors instead of lists in places where that makes sense. For example, in reading a Max dictionary into Scheme, arrays in the dictionary will be converted to vectors instead of Scheme lists. And s4m has functions for copying from tables and buffers to vectors, and vice versa. We won’t cover those here, but they are detailed in the s4m documentation.
; conversions
(vector->list '#(0 1 2 3))
s4m> (0 1 2 3)
(list->vector '(0 1 2 3))
s4m> #(0 1 2 3)
We can also make a vectors without specifying first what they will hold with make-vector:
; make a 4 point vector
(make-vector 4)
s4m> #( #<unspecified> #<unspecified> #<unspecified> #<unspecified> )
; this is more useful if we pass a starting value
(make-vector 4 0)
s4m> #(0 0 0 0)
s7 supports multi-dimensional vectors. We create these by passing a list to make vector where the vector size argument goes. The lists specifies the size in as many dimensions as we want.
; make a 2 x 3 vector, initialized to 0
(define v2x3 (make-vector (list 2 3) 0))
s4m> #2d((0 0 0) (0 0 0))
; read from the vector
(v2x3 1 2)
s4m> 0
; set with applicative syntax
(set! (v2x3 1 2) 99)
s4m> 99
v2x3
s4m> #2d((0 0 0) (0 0 99))
s7 has quite a few interesting additional vector functions, especially around multi-dimensional vectors, that you can read about on the official s7 page.
Hash-Tables¶
Hash-tables are key-value stores, similar to dictionaries in Python or JavaScript. A key can be anything we’d like, but it’s most common to use a keyword as a key, or barring that, a symbol.
;; create a hash-table, with keys :a and :b
(define my-hash (hash-table :a 1 :b 2)
s4m> (hash-table :a 1 :b 2)
;; read value at :a
(hash-table-ref my-hash :a)
s4m> 1
;; set value at :b
(hash-table-set! my-hash :b 99)
s4m> 99
Asking for a value that is not in a hash-table returns #f, and we can remove an item from a hash-table by storing #f at the key. We can put a new item in the hash-table by setting it’s value with a key.
;; ask for a value not in our hash
(hash-table-ref my-hash :c)
s4m> #f
;; add :c entry
(hash-table-set! my-hash :c 99)
s4m> 99
;; delete entry :b
(hash-table-set! my-hash :b #f)
s4m> #f
;; inspect our hash now, b is now gone
my-hash
s4m> (hash-table :a 1 :c 99)
As noted earlier, s7 Scheme supports applicative syntax for compound data types, and this works for hash-tables too, allowing us to get a value from a hash-table by calling the hash-table as a function with the key as an argument
; get :a, calling my-hash like a function
(my-hash :a)
s4m> 1
As with lists, calling the hash-table with a key gives us a memory location, and we can thus also use this with set!:
; set :a, with applicative syntax
(set! (my-hash :a) 42)
s4m> 42
Hash-tables can be nested.
(define deep-hash (hash-table :a 1 :b (hash-table :c 3 :d 4)))
s4m> (hash-table :a 1 :b (hash-table :c 3 :d 4))
Applicative syntax is very helpful for nested hash-tables. Note that this syntax only works for applicative syntax, not for hash-table-ref:
:get contents of :c, at contents of :b
(deep-hash :b :c)
s4m> 3
We can set this way too:
:set :b :c
(set! (deep-hash :b :c) 99)
s4m> 99
Be aware though, that trying to use a chain of keys is an error past the first non-existent key, for either getting or setting:
(define deep-hash (hash-table :a 1 :b (hash-table :c 3 :d 4)))
s4m> (hash-table :a 1 :b (hash-table :c 3 :d 4))
(deep-hash :z)
s4m> #f
(deep-hash :a :z)
s4m> #f
(deep-hash :z :x)
s4m> Error....
(set! (deep-hash :z :y :x))
s4m> Error....
If we stick to simple types as keys (numbers, symbols, keywords), we can convert hash-tables to Max dictionaries and vice versa, writing and reading from Max dictionaries. See the Scheme For Max documentation for details on these functions.
Branching with if¶
In Scheme, we typically branch using one of two special forms: if and cond. These are both special forms - they look like function calls but are not evaluated the same way as functions. The if special form takes three clauses. The first is the predicate, that which is tested to determine which branch we take. The second is the expression that is evaluated and returned if the predicate evaluates to true. And the third is the expression that is evaluated and returned if the predicate fails. Thus the value returned by an if expression is the value of evaluating either the first or second result clause. These clauses can be either simple values, or s-expressions that are evaluated to return a value. The reason if is a special form is that the s-expressions for the clauses only evaluate if that clause is to be returned.
;; return 99 if test-var is 33, else return 66
(define test-var 99)
s4m> 99
(if (= 99 test-var) 33 66)
s4m> 33
;; using the above to set a variable
(set! my-var (if (= 99 test-var) 33 66))
s4m> 33
;; an if statement that returns the results of s-exp evaluation
(if (= 99 test-var)
(+ 32 1)
(+ 66 4))
s4m> 33
Grouping statements with begin¶
So far, if looks just like a function. The fact that it is not a function is illustrated if we put side effects in our two clauses. If we want to add a side effect to a clause that will return a value, we can enclose child expressions in a begin statement. All expressions in the body of the begin are evaluated, but only the last expression is returned.
(begin 1 2 3)
s4m> 3
;; an if statement that returns the results of s-exp evaluation
(if (= 1 1)
(begin (post "first clause!") (+ 32 1))
(begin (post "second clause!") (+ 66 4)))
s4m: first clause!
s4m> 33
When we run the above, we see that our console only shows the output from the first clause. If if was a function, we would see the output from both clauses, because of the fact that expressions are evaluated from the inside out. The fact that if breaks the rules of normal function execution is what makes it a special form.
We don’t need to use a begin statement, we could just put side effect expressions in the slots, as long as we have made sure that it’s ok that the entire if form evaluates to whatever is returned in the clause (i.e. the null list, potentially).
In S7, we can skip the final clause in an if statement, in which case the return value of the if is unspecified if the predicate fails.
;; if var = 1, if evaluates to null, else to unspecified
(define var 2)
(if (= var 1)
(post "first clause!")) ;post returns null, so the if will too
s4m> <unspecified>
This is a good time to discuss predicates and truth in Scheme, because it’s a bit different from what you may be used to other languages.
In Scheme, only #false is false.
Repeat that three times. False can be expressed as either #f or #false, but nothing else ever equals false. Not zero (like C), not the null list (like Common Lisp), not an empty data structure. Nothing except #false!
;; only false is false!
(if 0
(post "I post!")
(post "but I don't, because I never get evaluated!") )
This is useful in Max, because Max has no notion of boolean True or False. In Max, we express booleans with 1 or 0. Which means that we can indicate an invalid Max value using Scheme’s #false, and we can test for a valid (or existing) value by using the value in a predicate. This will come in handy when we get to dictionaries and hash-tables.
Scheme has many predicate functions which returns #f if they fail, and end in a ?. For example, if we want to test whether a value is the null list (an empty list), we can use the null? predicate.
;; if var is the null list, post
(if (null? var)
(post "Var is the null list."))
We’ve seen some of these already, but some other useful predicates are defined?, procedure?, symbol?, number?, list?, keyword?.
It is idiomatic Scheme to name your own predicates similarly. Not all Scheme implementations have the same predicates built in, so if you look up a predicate online, you probably want to test it in the REPL to make sure it’s in S74, or add it to your base file.
Testing equality¶
Testing equality in Scheme is a bit different than you might be used to in other languages as well.
Numeric equality is tested with =, but note that we do not have a question mark. Types of numbers (integers, floats, fractions) will be properly cast to each other:
; testing numbers for equality
(= 1 1.0)
#t
(= 1 2/2)
#t
(define a 1)
(= a 1.0)
#t
Testing whether non-numeric values are the same can be done with eqv?. This tests whether the pointers point to the same thing.
; two vars to the same list are equivalent
(define a (list 1 2 3))
(define a-alias a)
(eqv? a a-alis)
#t
; but not equivalent to some other list with the same values
(eqv? a (list 1 2 3)
#f
; this works for functions and symbols too
(define var-pointing-to-post post)
(eqv? var-pointing-to-post post)
#t
(define the-sym 'my-symbol)
(eqv? the-sym 'my-symbol)
#t
(eqv? 'my-symbol 'my-symbol)
#t
; simple types are equivalent only if no cast is involved
(eqv? 1 1)
#t
(eqv? 1 1.0)
#f
Testing whether compound types are the same, element by element, can be done with equal?. This tests the contents of the compound type, not the pointers.
; test a list
(equal? (list 1 2 3) (list 1 2 3))
#t
(define l1 (list 1 2 3))
(define l2 (list 1 2 3))
; their contents are the same
(equal? l1 l2)
#t
; but they don't point to the same address in memory
(eqv? l1 l2)
#f
; this works for strings, symbols, and keywords too
(equal? "foo" "foo")
#t
(equal? 'foo 'foo)
#t
(define keyfoo :foo)
(equal? keyfoo :foo)
There is one more variant, eq?. In S7, eq? is almost entirely the same as eqv?, but this is not always the case in all Scheme implementations. For the most part, in S7 you can just use eq? and eqv? interchangeably. Different implementations vary in their treatment of the empty list (the “null list”), which we will cover in detail later.
; is the null list the same as the null list?
(eq? (list) (list))
; s7 says yes! (not all do)
#t
(eqv? (list) (list))
#t
When in doubt, test your equality checks in the repl! But in general, numeric equivalence uses =, non-numeric and compound type equality uses equal?, and pointer comparison uses eq? and/or eqv?.
Logical operators: and, or, not¶
Testing complex conditions often requires logical operators, for which Scheme provides us and, or, and not.
; and returns true only if all predicates return true
(and (= 1 1) (> 2 1) (< 1 2))
s4m> #t
; or returns true if any return true
(or (= 1 2) (= 1 1))
s4m> #t
; not returns the negation of a boolean
(not (or (= 1 2) (= 1 1)))
s4m> #f
These are special forms, not regular functions, meaning that evaluation doesn’t follow the regular function evaluation rules of evaluating all subexpressions and passing the results in as arguments. Rather, these short-circuit. This can be useful if we want to evaluate some expressions only if previous expressions have returned either true or false. Remember, in a boolean context, only #false is #false!
; evaluate the second expression only if the first is true
; note: the return value is from the last evaluated expression
(and (= 1 0) (post "I ran!"))
s4m> #f
If and were a function, we would see our post statement running regardless of the result of the first expression, but it only excecutes if all expressions return a non-false value:
(and (= 1 1) (post "I ran!"))
s4m: I ran!
s4m> ()
; add another non-false expression and it will be the return value
(and (= 1 1) (post "I ran!") 42)
s4m: I ran!
s4m> 42
This can be used with or as well, with expressions evaluating until one of them returns true. This can be a convenient way to make something happen if a previous something returns false. For example, we know that a hash-table returns false if asked for a non-existent key, so this can be used to create a fall-back value
(define h (hash-table :a 1 :b 2))
s4m> (hash-table :b 2 :a 1)
; get the value at a key, or some fall-back value
(or (h :a) 99)
s4m> 1
(or (h :c) 99)
s4m> 99
Branching with cond¶
The cond special form allows us to provide a series of predicate and result pairs. Evaluation stops when the first predicate passes. When combined with predicates and logical operators, this gives us everything we need to implement complex control flow.
;; return some numbers for several values of x
(cond
((= x 1) (+ 9 x))
((= x 2) (+ 8 x))
((= x 3) (+ 7 x)))
;; to illustrate that these are just pairs of expressions,
;; here's a cond that returns 99
(cond (#f #f) (#t 99))
If no clause succeeds, cond will return unspecified (at least in S7!). To avoid this, it is common to return #f in an else clause. Interestingly, else is just a short-form for returning true - all we need is a predicate that passes.
;; return 10 for several values of x, or false for unhandled instance
(cond
((= x 1) (+ 9 x))
((= x 2) (+ 8 x))
(else #f))
;; because only false is false, this technically works too
;; but you won't be popular coding like this....
(cond
((= x 1) (+ 9 x))
((= x 2) (+ 8 x))
(0 #f))
Again, if we want conditional side effects, we can use begin:
;; branching with side effects
(cond
((= x 1)
(begin
(post "x is 1")
(+ 9 x)))
((= x 2)
(begin
(post "x is 2")
(+ 8 x)))
(else
(begin
(post "unhandled x!")
#f)))
Scopes with the let statement¶
In computer science, ‘scope’ referes to where and when the binding of a symbol to a variable or function is in effect. Scheme is a lexically scoped language, allowing us to use functions and scopes in powerful ways, some of which we will look at in this book. To use Scheme effectively, and to take advantage of its lexical scoping for real time interactivity in Max, we need to understand Scheme scoping and how to use the let form.
When we make definitions in scm file or send them to the interpreter from Max messages, bindings execute in the global scope, also refered to as the “top-level scope”. These bindings are visible in any other expression or function, unless shadowed by bindings local to the expression or function.
;; make a global variable
(define var 99)
s4m> 99
;; define a function, it can access var
;; if we tried to run this function prior to defining var
;; we'd get an error
(define (my-fun)
(post "var:" var)
; return var + 1
(+ 1 var))
s4m> my-fun
(my-fun)
s4m: var: 99
s4m> 100
;; change var in the global scope & the change is visible
;; in the body of the function
(set! var 100)
s4m> 100
(my-fun)
s4m: var: 100
s4m> 101
If we change a variable from an outer scope inside a function body, by using set!, this will change the variable in the outer scope. A common convention in Scheme is to name functions ending in an exclamation mark if they have side-effects on external definitions.
;; make a global var, var
(define var 99)
s4m> 99
;; define a function that access and mutates var
(define (my-fun!)
; set outer var, and return the value
(set! var (+ 1 var)))
s4m> my-fun!
(my-fun!)
s4m> 100
; var has changed in the global scope
var
s4m> 101
Function parameters create bindings that are active in the function body, making an inner scope. This is also called “function scope”. The function scope will have the values of the arguments passed to the function bound to the symbols used as function parameters.
;; make a function with a local binding
(define (my-fun-2 var)
(post "var in my-fun-2:" var)
(set! var (+ 1 var))
(post "var in my-fun-2 now:" var)
; return var
var)
s4m> my-fun-2
;; call it
(my-fun-2 42)
s4m: var in my-fun-2: 42
s4m: var in my-fun-2 now: 43
s4m> 43
;; make a global variable with the same name, 'var'
(define var 42)
s4m> 42
;; call our function with it, returns 43 as before
(my-fun-2 var)
s4m: var in my-fun-2: 42
s4m: var in my-fun-2 now: 43
s4m> 43
;; check our global var - no change!
(post var)
s4m: 42
So what’s going on here? The local binding of the symbol var in my-fun-2 is separate from the global binding; it’s a new variable that happens to have the same name. This results in the new variable - var in the scope of my-fun-2 - shadowing the global variable. When we use set! inside my-fun-2, only the local version is updated. After the function exits, its scope becomes inactive and the symbol ‘var’ will again refer to the global variable.
The let special form creates a local scope. It takes an expression with a series of bindings of symbol and value, and a body that is executed with those bindings. The let statement returns the value of the last expression in the body. Within the body of the let, any bindings defined by the let’s first clause will shadow any identically named bindings in outer scopes. Unlike a function, a let executes its body right away.
;; make a scope with two local bindings
(let
((a 1) (b 2)) ; bindings
(+ a b)) ; body, does addition, returns value
s4m> 3
;; the body can have many expressions
;; the value returned by let is the last one
(let ((a 1) (b 2)) ; bindings
(post "a:" a) ; body with 3 expressions
(post "b:" b)
(+ a b))
s4m: "a:" 1
s4m: "b:" 2
s4m> 3
As far as scoping rules are concerned, variables defined by a let are treated in the body of the let exactly the same way as function paramaters are treated in the body of a function. Under the hood, they are equivalent. These two are completely equivalent:
; use a let
(let ((a 1) (b 2))
(+ a b))
s4m> 3
; use a lambda and call it immediately
((lamdba (a b)(+ a b)) 1 2)
s4m> 3
In Scheme, a let literally is an immediately executed lambda. This is worth taking a moment to understand!
A regular let has all bindings defined at the same time, (order not guaranteed) meaning that a binding cannot refer to a previous binding:
; an error, the second binding won't work!
(let ((a 2) (b (* a a)))
(+ a b))
However, we can do this if we use let*:
; OK!
(let* ((a 2) (b (* a a)))
(+ a b))
s4m> 6
Under the hood, this actually executes as two nested lets:
(let ((a 2))
(let ((b (* a a)))
(+ a b)))
We can use a let in the body of a function to create temporary variables local to a function.
; define a function with an inner let
; the last sexpr in the let is returned by the let
; and thus also by my-fun
(define (my-fun a)
(let ((b 1) (c 2))
(+ a b c)))
(my-fun 3)
s4m> 6
Looping¶
Looping in Scheme is also a bit unusual compared to other languages. If you’re used to languages with a for-loop, you might be surprised to find there isn’t one! Instead, we use a variety of functional programming constructs, in which the body of the loop is replaced by a call to a function. This is not as awkward as it might at first sound though, because lambda makes it easy to create temporary functions.
Map and for-each¶
The simplest looping constructs in Scheme are map and for-each. These are similar in that in each, we pass them two arguments: a function, and a list. The function is then repeatedly evaluated over each item in the list, with the list item used as the argument to the function. The difference between these two is that map returns a list of the results, while for-each is called for the side effect of calling the function, without collecting up the results in a new list.
In the example below, we pass map a function that returns the value of its single argument incremented by 1, and a list of integers. The call to map returns a new list, where each item is the old list item incremented by 1.
; a function to increment an argument by one, and a list
(define (add-1 x) (+ 1 x))
(define my-list (list 1 2 3))
; get a new list by calling map
(map add-1 my-list)
s4m> (2 3 4)
Of course, we don’t need to pre-define either the function or list.
(map
(lambda (x) (+ 1 x))
(list 1 2 3))
s4m> (2 3 4)
If we don’t need the values returned from our looping construct, but rather want to trigger an event, we use for-each. Because we aren’t calling it for the return value, for-each returns #<unspecified>.
; for-each will execute the functions, return #<unspecified>
(for-each
(lambda (x) (post "loop pass, x is:" x))
(list 1 2 3))
s4m: loop pass, x is: 1
s4m: loop pass, x is: 2
s4m: loop pass, x is: 3
s4m> #<unspecified>
If we want to combine side-effects and collection of values, we can have our function create the side-effect prior to returning its result:
; produce a side-effect, and collect the incremented value
(for-each
(lambda (x)(
(post "loop pass, x is:" x)
(+ 1 x)))
(list 1 2 3))
s4m: loop pass, x is: 1
s4m: loop pass, x is: 2
s4m: loop pass, x is: 3
s4m> (2 3 4)
If you’re used to for loops, you might be wanting to iterate over an index within a numerical range. We can do this by using the range function to create our list of index numbers:
; for-each will execute the functions, return #<unspecified>
(for-each
(lambda (x) (post "loop pass, x is:" x))
(range 0 4))
s4m: loop pass, x is: 0
s4m: loop pass, x is: 1
s4m: loop pass, x is: 2
s4m: loop pass, x is: 3
s4m> #<unspecified>
A nice feature of both map and for-each is that they can take any number of collections over which to iterate, and will use one from each as arguments to the function. Here’s an example of using this to make a list of lists:
(map
(lambda (x y) (list x y))
(list :a :b :c) ; first collection
(list 1 2 3)) ; second collection
s4m> ((:a 1) (:b 3) (:c 3))
The asute reader will have noticed that in this case, our lambda is optional, because we could just use the list function itself!
; use list as the function
(map list (list :a :b :c) (list 1 2 3))
s4m> ((:a 1) (:b 3) (:c 3))
If the lists are not equal in length, iteration stops when the first one runs out.
; uneven lists stop at the shorter lens
(map list
(list :a :b :c)
(list 1 2 3 4 5 6))
s4m> ((:a 1) (:b 3) (:c 3))
; this can be handy combined with range and length
(define fruits (list 'apple 'pear 'banana))
(map list
(range 0 (length fruits))
fruits)
s4m> ((0 apple) (1 pear) (2 banana))
Looping with recursion¶
The second most common option for looping in Scheme is using functions recursively. We can have a function call itself until a condition is met. This requires us to have an if or cond statement in the function, with one branch that stops the loop and the other that continues it. The stopping branch is called the “base case”, and is written normally first. It returns a value that will be the return value of the whole loop. The other branch must call the function again, typically with an argument that is altered such that the loop only runs a finite number of times. For example, here is a function that recurses 4 times, counting down from 4 to 1:
; our looping function
(define (count-down x)
(post "count-down, x:" x)
(if (= x 1)
; the base case, stop by returning x
x
; otherwise, re-run with x decremented
(count-down (- x 1))))
; now run it!
(count-down 3)
s4m: count-down, x: 3
s4m: count-down, x: 2
s4m: count-down, x: 1
s4m> 1
A more real-world example of recursion would involve doing something with the argument, so that the base case returns something that was calculated from the recursive calls. Here’s an example of calculating a factorial. If you’re not familiar with a factorial, the factorial of a number is the result of multiplying a number by all the numbers smaller than that number. So factorial 4 (written 4!) is 4 x 3 x 2 x 1.
(define (factorial x)
(post "factorial call, x is:" x)
(if (= x 1)
; the base case, return 1
1
; otherwise, return the value of the current
; pass multiplied by the next recursion
(* x (factorial (- x 1)))))
; runnning should return 3 x 2 x 1
(factorial 3)
s4m: factorial call, x is: 3
s4m: factorial call, x is: 2
s4m: factorial call, x is: 1
s4m> 6
If you’re used to other programming languages you may be wondering how this could possibly be efficient, with a stack-frame created for each call. Won’t we run out of memory if using a very large value for the count? (If this means nothing to you, don’t worry about it…) The answer is that Scheme uses tail-call optimization. If the recursive function call is the last expression in the body of the function, the interpreter knows that it’s safe to implement the function recursion as a jump, under-the-hood. This means that we don’t actually make a new stack frame for each call, and thus tail-call recursion is efficient and safe. Recursion in Scheme is a big topic, and we will look at common patterns in future chapters.
Recursion with named let¶
Recursion can be confusing while you get used to it, and sometimes the syntax is just more verbose than it needs be, so Scheme includes an alternate way of looping that is secretely recursion, but looks much more like a “normal” loop. Named-let looks like a cross between a function call and a let statement, which makes sense when you remember that let and lambda are really the same thing in different syntax.
When we use named-let, we create a let block, but begin by giving it a name. Then we have any number of variable initializations, like a normal let. These are the starting values for the variables. Finally, when we call the name as if it’s a function, we use new arguments and the intepreter starts the let block again, with the arguments replacing the initial values for the let variables. As with recursive functions, we need a test to see if we should loop again, and a return value that is returned when we’re done looping.
Let’s start as simply as possible with our count-down again:
; name is count-down-loop, let vars consists of x and y
; because this is a let, it runs right away
(let count-down-loop ((x 3))
; body of the let
(post "x is: " x)
; if x is still greater than 1, repeat
(if (> x 1)
(count-down-loop (- x 1))))
s4m: x is: 3
s4m: x is: 2
s4m: x is: 1
s4m> #<unspecified>
A more complex example might return something from the let. Remember, a let returns its last expression. We’ll make a named-let to calcuate a value, x, to some power, y.
; return x to the y: 2 to the 3rd power
(let exp-loop ((x 2) (y 3))
(post "exp-loop, x:" x "y:" y)
; if y is greater than one, repeat
(if (> y 1)
; on each pass, x is replaced with x times 2
(exp-loop (* x 2) (- y 1))
; if y is 1, return the value of x
x))
s4m: exp-loop, x: 2 y: 3
s4m: exp-loop, x: 4 y: 2
s4m: exp-loop, x: 8 y: 1
s4m> 8
Note that unlike recursion with a function, the binding for exp-loop is only valid in the let. We can’t call exp-loop from outside of the let, as if it’s a function afterwards. For illustration, here is the exact same construct, but implemented as an immediately executed function:
; as named let, executing immediately
(let exp-loop ((x 2) (y 3))
(if (> y 1)
(exp-loop (* x 2) (- y 1))
x))
s4m> 8
; as a function that is then called
(define (exp-function x y)
(if (> y 1)
(exp-function (* x 2) (- y 1))
x))
s4m> exp-function
(exp-function 2 3)
s4m> 8
; with the function, we can call it again
(exp-function 2 3)
; whereas is exp-loop is no longer in scope
(exp-loop 2 3)
s4m: s4m Error: ;unbound variable exp-loop in (exp-loop 2 3)
With any kind of recursion, we have to be careful not to get stuck in an infinite loop. Scheme For Max doesn’t provide any kind of protection here: Max will lock up and you will need to restart it. This is no different than with the JS object, but because recursion is easier to read in Scheme, you’re more likely to encounter it. Test your loops!
Looping with while¶
Though not part of the various Scheme standards, s7 also provides an implemention of the while loop. This is convenient when we want a simple, imperative loop, with the option to abort or continue. s7 is an unopinionated Scheme dialect, in that it doesn’t force us to program in a functional style.
While expressions consist of a condition and a body. The body is executed repeatedly as long as the condition is true. Additionally, we can abort execution of the body, jumping back to the beginning with continue, or break out of the loop entirely with break. We can combine this with the let form to ensure the variables we use in while are local.
(let ((count 0))
(while (< count 3)
(post "count:" count)
(set! count (+ 1 count))))
s4m: count: 0
s4m: count: 1
s4m: count: 2
s4m> ()
Here’s an example using break and continue with random, a construct we might use in a musical algorithm.
(let ((count 0))
; execute a maxium of 8 times
(while (< count 8)
(post "count:" count)
; a 1 in 4 chance we quit after each time
(if (= 0 (random 4))
(begin (post "aborting!") (break)))
; a 1 in 4 chance we stay on the same number
(if (= 0 (random 3))
(begin (post "continuing!") (continue)))
(set! count (+ 1 count))))
s4m: count: 0
s4m: count: 1
s4m: count: 2
s4m: count: 3
s4m: aborting!
s4m> ()
Conclusion of Part 1¶
Congratulations! You know now enough Scheme to productively work in Scheme For Max. To learn about the Max specific s4m functions, check out the Scheme For Max Documentation.
Future plans for this e-book include chapters on Lisp programming idioms and further narrative content on Scheme For Max common practices and recipes. You can follow the repository on GitHub to receive announcements. Also, please feel free to submit feedback via the GitHub issue tracker for this repository.


[ Home | Overview | Publications | Software/Downloads ] • [ Documentation/Questions | Training Videos and Slides ] • [ People | Acks ]
HPCToolkit is an integrated suite of tools for measurement and analysis of program performance on computers ranging from multicore desktop systems to the nation's largest supercomputers. HPCToolkit provides accurate measurements of a program's work, resource consumption, and inefficiency, correlates these metrics with the program's source code, works with multilingual, fully optimized binaries, has very low measurement overhead, and scales to large parallel systems. HPCToolkit's measurements provide support for analyzing a program execution cost, inefficiency, and scaling characteristics both within and across nodes of a parallel system.
HPCToolkit works by sampling an execution of a multithreaded and/or multiprocess program using hardware performance counters, unwinding thread call stacks, and attributing the metric value associated with a sample event in a thread to the calling context of the thread/process in which the event occurred. Sampling has several advantages over instrumentation for measuring program performance: it requires no modification of source code, it avoids potential blind spots (such as code available in only binary form), and it has lower overhead. HPCToolkit typically adds only 1% to 5% measurement overhead to an execution for reasonable sampling rates. Sampling using performance counters enables fine-grain measurement and attribution of detailed costs including metrics such as operation counts, pipeline stalls, cache misses, and inter-cache communication in multicore and multisocket configurations. Such detailed measurements are essential for understanding the performance characteristics of applications on modern multicore microprocessors that employ instruction-level parallelism, out-of-order execution, and complex memory hierarchies. HPCToolkit also supports computing derived metrics such as cycles per instruction, waste, and relative efficiency to provide insight into a program's shortcomings.
A unique capability of HPCToolkit is its nearly flawless ability to unwind a thread's call stack. Unwinding is often a difficult and error-prone task with highly optimized code.
HPCToolkit assembles performance measurements into a call path profile that associates the costs of each function call with its full calling context. In addition, HPCToolkit uses binary analysis to attribute program performance metrics with uniquely detailed precision -- full dynamic calling contexts augmented with information about call sites, source lines, loops and inlined code. Measurements can be analyzed in a variety of ways: top-down in a calling context tree, which associates costs with the full calling context in which they are incurred; bottom-up in a view that apportions costs associated with a function to each of the contexts in which the function is called; and in a flat view that aggregates all costs associated with a function independent of calling context. This multiplicity of perspectives is essential to understanding a program's performance for tuning under various circumstances.
By working at the machine-code level, HPCToolkit accurately measures and attributes costs in executions of multilingual programs, even if they are linked with libraries available only in binary form. HPCToolkit supports performance analysis of fully optimized code -- the only form of a program worth measuring; it even measures and attributes performance metrics to shared libraries that are dynamically loaded at run time. The low overhead of HPCToolkit's sampling-based measurement is particularly important for parallel programs because measurement overhead can distort program behavior.
HPCToolkit is especially good at pinpointing scaling losses in parallel codes, both within multicore nodes and across the nodes in a parallel system. Using differential analysis of call path profiles collected on different numbers of threads or processes enables one to quantify scalability losses and pinpoint their causes to individual lines of code executed in particular calling contexts. We have used this technique to quantify scaling losses in leading science applications (e.g., FLASH, MILC, and PFLOTRAN) across thousands of processor cores on Cray XT and IBM Blue Gene/P systems and associate them with individual lines of source code in full calling context, as well as to quantify scaling losses in science applications (e.g., S3D) within nodes at the loop nest level due to competition for memory bandwidth in multicore processors.
HPCToolkit also includes support for measurement and analysis of applications on GPU-accelerated systems. On systems using AMD, Intel, or NVIDIA GPUs, HPCToolkit can profile and trace GPU operations including kernel executions, memory copies, and synchronization. On NVIDIA GPUs, HPCToolkit can use PC sampling to measure instruction execution and stalls. Using results from analysis of both CPU and GPU binaries, HPCToolkit can attribute fine-grain measurements of GPU computations to heterogeneous calling contexts that may include host procedures, GPU kernels, device procedures, inlined templates and functions, loops, and source lines.
HPCToolkit is deployed on several DOE leadership class machines, including a Theta (Cray XC40) and ThetaGPU (NVIDIA DGX A100) at Argonne's Leadership Computing Facility, Summit (IBM Power 9 + NVIDIA V100) at ORNL, as well as Cori (Cray XC40) and Cori-GPU at NERSC.
[Page last updated: 2021/06/12]


{% extends "base.html" %} {% load compress hc_extras humanize static %} {% block containers %}
A High performance e-commerce storefront built with Python,Django, and ReactJS.
UX and UI: Designed for a user experience that rivals even the top commercial platforms
Orders: A comprehensive system for orders, dispatch and refunds
Dashboard: Administrators have total control of users, processes and products
Cart : Advanced payment and tax options, with full control over discounts and promotions
SEO: Packed with features that get stores to a wider audience


In this blog post I am going to write about a programming language which I have not checked out before. Typescript is a super set of Javascript and is developed by Microsoft. The syntax is exactly the same as Javascript with one very important difference: in comparison to Javascript Typescript knows the concept of types and checks them with a built in type system.
To make type failure messages more useful Typescript is also a compiled language while Javascript is an interpreted language. That means that Typescript files are checked by a program (the compiler) which checks for general syntax problems or undefined property access. The biggest advantage of Javascript is at the same time also the biggest problem: its dynamic behaviour. You can create cery rich and cool prototypes in no time but it is hard scalable.
Creating interfaces for modules or functions depends often on rich documentation. Documentation is great and important but it is in this case nothing else than a type system written down in plain english instead of something the computer could understand to help you write your code the right way. Typescript adds this with its type system. Look at this method declaration and usage in Javascript:
function getName(obj) {
return obj.name
}
let person = {
name: "Rainer Zufall"
}
let name1 = getName(person)
let number = 5
let name2 = getName(number)
This is totally valid Javascript but will set name2
to undefined
since the number
does not have a name property. A compiler with a type system like Typescript checks for this violation and does not compile the code without an error. The same code in Typescript looks like this:
function getName(obj: { name: string }): string {
return obj.name
}
As you see, the compiler shows an error if you try to use the function with a wrong parameter:
By the way: I use Visual Studio Code for programming, it has very great Typescript-functionality built it and works really great. Since Typescript is a super set of Javascript you can also just write Javascript in your .ts-files and spare the convenience of type information.
Before I continue with the most important features of the type system, here is a short introduction how to install the compiler and use it with other editors:
$ # Install typescript via npm/yarn
$ yarn global add typescript
$ # Use the Typescript compiler (tsc) to compile a given .ts file
$ tsc main.ts
When compiling a file, the compiler creates the generated Javascript file. Pay attention: the file is also created if the compiler shows an error! You can compile multiple files at once and even specify an output directory for the generated code. But if your project gets bigger than a file I would still recommend to use Visual Studio Code instead.
The Type System
To declare a variable with a given type, you use the let variable: string
syntax. If you than try to assign a value of an expression that does not match the given type, you will get a useful error. I already showed that it is also possible to declare the type by giving an object like syntax with types to enforce special properties: let human: {name: string, gender: Gender}
. To make this more scalable, it is also possible to define interfaces:
enum Gender {
male, female
}
interface Person {
name: string
gender: Gender
}
let p: Person = {
name: "Rainer Zufall",
gender: Gender.male
}
A very helpful feature is the autocompletion of Visual Studio Code while defining the actual object. This is something that is not possible in Javascript since objects are so dynamic that they could contain literally anything. In Typescript you can also create classes which implements defined interfaces:
class Student implements Person {
name: string
gender: Gender
discipline: string
constructor(name: string, gender: Gender, discipline: string) {
this.name = name
this.gender = gender
this.discipline = discipline
}
greet() {
console.log("Hello " + name + "!")
}
}
let p = new Student("Benjamin Herzog", Gender.male, "Computer science")
p.greet()
Another very important feature is the presence of optional parameters. Sometimes when defining an interface you would like to give the implementing types some freedom. Some properties are not necessary but if they are present, they should be handled. That can be done with optional properties:
interface Person {
name: string
phoneNumber?: string
}
// valid, because phoneNumber is optional
let p1: Person = {
name: "Rainer Zufall"
}
let p2: Person = {
name: "Clair Grube",
phoneNumber: "+491626194826"
}
Generics
A strong type system should of course also provide the possibility to use generics. Generics gives the programmer the possibility to write functions that work dynamic with different types without the need of writing multiple functions. The function also does not need to know which specific type it operates it, often only a given property or method is needed. This can be achieved with interfaces. Here is a simple example:
interface Namable {
name: string
}
function getName<T extends Namable>(obj: T): string {
return obj.name
}
getName({name: "Ben"}) // valid
getName({age: 25}) // invalid
getName({name: "Ben", age: 25}) // valid
Another example shows the strong type system in the dynamic world of Javascript:
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
const obj = {
name: "Ben",
age: 25
}
getProperty(obj, "name") // valid
getProperty(obj, "phone") // invalid
getProperty(obj, "age") // valid
Since objects in Javascript are like dictionaries/maps in other languages they are very dynamic and their properties can even be accessed through subscripts. In the example above the type system checks that the string (!!) that is given to the method as the second parameter is a valid property name of the first parameter. For me as a Swift developer this is totally crazy and really cool!
Now some other advanced type constructs that are not possible in Swift:
Merged types:
const p1 = {
name: "Ben"
}
const p2 = {
age: 25
}
function mergedPerson<T, U>(obj1: T, obj2: U): T & U {
let r = <T & U>{}
for (let p in obj1) {
(<any>r)[p] = obj1[p]
}
for (let p in obj2) {
(<any>r)[p] = obj2[p]
}
return r
}
let p3 = mergedPerson(p1, p2)
p3.name // "Ben"
p3.age // 25
Union types: (Could in Swift be expressed with enums)
function getSringOrNumber(parameter: number): string | number {
if (parameter == 42) {
return "Answer of life"
}
return 42
}
More string checking:
type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'
function request(method: HTTPMethod) {
// do something
}
request('GET') // valid
request('UPDATE') // invalid
There are a lot more features, but those were the most important ones. I think Typescript is a really rich language and has a lot of potential, I think the guys at Microsoft are doing a great job! If you would like to know more about the language, check out the official website.
Thanks for reading this blog post! I know it came a bit late and I struggle a bit with the weekly blog posts. I just do not want to write a blog post just for the purpose of writing. The main focus is on learning new things. Writing a blog post about Typescript forces me to get to know more about the topic, which is really great. It is just hard to read and try that much stuff for cool topics beside my studies, jobs and other projects. I have another update regarding by programming language lbd which I did not touch for a while. I will write a post about it tomorrow. See you there!


Hey, nice to meet you. I'm Mike. I'm a Web Developer based in Vancouver, BC. This is my slice of the internet.
I like to talk about a lot of stuff. Mostly development stuff that I've learned about and felt like sharing, but also some stuff about board games and other interests.
If you're interested in me for a project I can do a bunch of stuff. Backend and DB design, devops and cloud deployments, SPAs and front-end minimalism. Most of my code is PHP, JavaScript, or Node, and my cloud expertise is in AWS, Heroku, Digital Ocean, and that sort of stuff. I've also done a bit of WordPress and Jekyll work, if you're into that. ;)
Check out my Blog and personal Projects, dive into my semi-not-regularly updated Thoughts, or hit me up on Twitter. Whether you're interested in me for a project or just want to chat, I'm always happy to talk.


|
Mini Project
KAUN KAREGA GENESI ME STEPin
|
Header file for Quiz progra,. More...
Go to the source code of this file.
Data Structures | |
| struct | qna_t |
| Structure for addressing every question read from file. More... | |
Typedefs | |
| typedef struct qna_t | qna_t |
| Structure for addressing every question read from file. More... | |
| typedef enum error_t | error_t |
| enumeration of return for functions depicts the type of returns for functions depending on different cases More... | |
Enumerations | |
| enum | error_t { SUCCESS = 1 , NO_FILE = 0 , NULL_PTR = -1 , PLAYER_OUT = -6 } |
| enumeration of return for functions depicts the type of returns for functions depending on different cases More... | |
Functions | |
| void | delay (int number_of_seconds) |
| simple delay function using inbuilt Time.h header file. More... | |
| error_t | file_read (qna_t *question_array, char *file_name) |
| reads csv file and stores data into array of structure More... | |
| qna_t * | create_array_of_questions (const int no_of_questions) |
| dynamically allocate memory for array. More... | |
| error_t | play_the_game (qna_t *question_array, char *name_of_participant, const int no_of_questions) |
| function to start playing the game and counting score More... | |
| void | introduction (void) |
| introduction of the quiz. More... | |
| void | help (void) |
| help function for contestants More... | |
Variables | |
| qna_t * | question_array |
Header file for Quiz progra,.
enumeration of return for functions depicts the type of returns for functions depending on different cases
| enum error_t |
| qna_t* create_array_of_questions | ( | const int | no_of_questions | ) |
dynamically allocate memory for array.
| void delay | ( | int | number_of_seconds | ) |
simple delay function using inbuilt Time.h header file.
| number_of_seconds |
reads csv file and stores data into array of structure
| pointer | to array of structure where questions are to be stored. |
| name | of file to be read |
| void help | ( | void | ) |
help function for contestants
| void introduction | ( | void | ) |
introduction of the quiz.
| error_t play_the_game | ( | qna_t * | question_array, |
| char * | name_of_participant, | ||
| const int | no_of_questions | ||
| ) |
function to start playing the game and counting score
| question_array | |
| score |
|
extern |


How do I mark a ship for a color?
Drag her from the "reserved" list at the bottom, onto designated dropping boxes for each color.
How do I remove a ship from a colored box?
Click on her face.
I cannot remove a ship from a colored box?
You cannot removed ships already locked-in game, and are signified by the icon's transparency.
When I click "Clear All", some ships remained
As I said, ships already locked-in game are also locked on the colored boxes here.
The ships get re-arranged after refreshing
Do not mind the arrangements. This page's goal is to let you plan for the whole fleet's separation into different operations, not to arrange your compositions.
Can you add ship-type filters on the reserved ships list?
No. Find desired ship types from the list yourself.
What's the 5th purple-ish box? There's no tag like that on the event.
So that I won't need to edit it again in case the future events do get five ship locking categories.
Will you make a button that will divide my ship list for me?
wtf are you talking about? :v


Current time-code:
Parsed frames: 0 average p/s: 0
Decoded frames: 0 average p/s: 0
Presented frames: 0 average p/s: 0
Painted frames: 0 average p/s: 0
Average paint delay: 0s


Beta This is a test version of the layout of this page. Take the survey to help us improve it
Guidance
Resource supporting teachers, initial teacher trainees, headteachers and leadership teams working with pupils on the autism spectrum.
The aims of this programme on the autism spectrum are to improve outcomes for pupils on the autism spectrum and increase knowledge and understanding among professionals about the autism spectrum. It also aims to share good practice so that professionals in mainstream schools can make adjustments to their policies, practices, procedures and curriculum that will enable more young people on the autism spectrum to benefit from a mainstream education.
This resource on the autism spectrum may be used in a variety of ways and by a range of users. Ideally, the units should be introduced in sequence because later units build on the activities and video clips in earlier units and assume an understanding of language and information.


Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Many people doesn’t not afraid of diseases; they afraid of health care system. Improper guidance and half knowledge from internet sources make them confused and they lose peace of mind. It leads to psychological stress.
People struggle to get better health care everyday irrespective of their status. They are worrying about their health. They are always searching for better health care. In the process of searching and getting better health care, they are losing valuable time. 70% of people are roaming around the hospitals for the second opinion from another doctor.
After a long standing wait they will get diagnostic reports and medicines. If they need to visit the doctor again with reports, it is another challenge for them.
Bargaining with ambulance driver when we are in urgency and roaming around the blood banks for the blood and its related products are like hell to the attendants.
One more challenging task for them is claiming insurance for their persons. At the time of paying insurance people do hear sweet words which they can’t hear in their life. But at the time of claiming insurance, they are losing themselves in the process of documentation.
80% of health care system in India belongs to private sector. Referral system is not very well organized in our country. Some people are failing to get diagnosed in the process of taking health care due to lack of proper guidance. In case of chronic diseases, immunological diseases and cancers early diagnosis plays key role in the curative treatment. In India, most of the cancer deaths are occurring due to late diagnosis.
Coming to the health sector, people whether they are educated or uneducated they are can’t understand many things and terminology. Many times they are failing to take right decisions either they are spending too much for small problem or they are not taking proper care for their illness.
We are ready to date to take care of the people by organizing the things in medical sector. We guide people to get benefited from health sector and we save their time. We build hassle free health care system for everyone in this country.


About
Work
Contact
Hello this is my portfolio!
I'm a web developer
Puppies project
Blue project
showit


Here there is a straight-forward Bar chart that uses the dollar events to add some interactivity to the chart. When the second bar is clicked a ModalDialog is shown to the user. This dialog could then show further information to the user.
<script src="RGraph.common.core.js"></script> <script src="RGraph.common.dynamic.js"></script> <script src="RGraph.bar.js"></script> <script src="RGraph.modaldialog.js"></script>Put this where you want the chart to show up:
<canvas id="cvs" width="650" height="250"> [No canvas support] </canvas>This is the code that generates the chart - it should be placed AFTER the canvas tag(s):


1)
Bob
he
2)
Mrs. Smith
she
3)
stomach
it
4)
people
they
5)
Susan and I
we
6)
floor
it
7)
dad and mom
they
8)
aunt
she
9)
Tony and I
we
10)
nail
it
11)
farmer
he
12)
plants
they