A language tutorial by Laurie Cheers.
Welcome to Swym. This programming language is designed to let you Say What You Mean, as clearly and elegantly as possible. (It's pronounced "swim", in case you were wondering.)
Convenient links:
I designed Swym in a crazy way - I wrote down some programs I wanted to be able to write, regardless of whether they were implementable; and then I reverse-engineered semantics for them. That process showed me how I needed to change the programs, to make them behave more consistently, and to make them parseable. It took about five years of iterating like this, on and off, before the language finally started to gel enough to be implementable. I hope you like the results. If nothing else, the process seems to have given Swym a unique flavour.
The interpreter is currently implemented in Javascript. This isn't intended to be permanent - just for this proof-of-concept implementation. For the same reason, don't be surprised if you experience any slowdowns: at the moment this language isn't optimized at all. Seriously; not. at. all. I decided I preferred getting it working over getting it fast.
I wrote it in Javascript partly because I wanted to learn Javascript better, but mostly to let me embed a command line in this webpage, like this...
Click Run to see the output. (You'll need Javascript enabled on your browser, of course.)
Each time you click you're running the Swym interpreter, live in your web browser. Feel free to rewrite any of the examples on this page and run them to see what you get.
You can also click the +/- button to expand the text boxes, or click Revert if you've deleted the original text and want to get it back.
But hey, maybe you're in a hurry, and you just want to get a flavour of what the language is like. Well, here's a little buffet of code examples. Read on for full details...
Non-intimidating functional programming style:
Multi-values:
The etc keyword:
Patterns: (Try clicking this one more than once...)
This part of a language tutorial is always tedious, so I'll try to make it quick. Swym is designed to be at least somewhat familiar to anyone who knows a C-like language, such as Java, C#, Javascript... or C itself, of course. Swym has the standard C-style comments (/* */
and //
), string syntax ("Hello\nWorld!"
), arithmetic operators (+ - * / % += -= *= /= %= ++ --
), and logical operators (== != < > <= >= && || !
), all with the standard precedence. All the basic stuff you see in all these languages. Control expressions also resemble the ones in C - for example, if(x){ return x } else { return y }
. And yes, you can use semicolons to separate statements - but they're mostly optional.
(FYI, since this is implemented in Javascript, all numbers are implemented as double-precision floats. Thus the division above is floating-point division. I haven't decided whether I want to keep this behaviour permanently.)
Yes, function calls look pretty familiar too. Calling print(
whatever)
will cause the specified value to be shown in the output window (without halting your program). If your program halts without doing any output at all, it'll automatically output the result of the last expression. That's what was happening with the minimalist "Hello World" above.
There's also the function println
, which does the same thing as print
, except with an added line break. Let's define our own, to see what function declarations look like:
There are two declarations here - 'myPrintln'
, and 'x'
. Notice that in order to declare something, we always write its name in single quotes. With just this one rule, you can read any Swym program and immediately figure out which bits of code are declaring which identifiers. (This can be surprisingly difficult in some languages!). Names are case sensitive.
Another thing to notice in this example is Swym's flexible syntax. A single-argument function call can be written function-call style (myPrintln(x)
), or member-access style (5.myPrintln
) with no difference in meaning. You can also mix styles in a single expression (myPrintln(5.square)
). This distinction is entirely aesthetic. I usually find a line is more readable when written in one way or the other.
(Actually, that not even the whole story; the ~
(tilde) operator also denotes a function call. Its precedence is higher than the dot operator. It's intended to be used to write out a chain of function calls, without needing to worry about matching up the open and close brackets. For example, print~sum~of~distinct~factors~of~x
is equivalent to x.factors.distinct.sum.print
. The function of
is a no-op: it just returns its argument unchanged. Its only purpose is to beautify expressions like this.)
Functions can also take more than one argument, but it would cause confusion if we allowed the same flexibility there (We can't have a.given(b)
mean the same as given(a,b)
)! So a function with more than one argument must be called either prefix or infix style, whichever it was declared with.
Also note: 'x' = "hello"
above is declaring a constant. You can't modify it after the initial definition. x
will contain the value "hello", forever. Swym does have variables too, but we need to introduce a few more concepts before we get to those.
Finally, you'll have seen that the definition starts with the word Anything
. That's the type signature of this function - in this case, not that interesting. Anything
is the universal type: it matches any value at all. Note that by convention, all Swym types start with a capital letter.
There are 8 basic data types in Swym:
true
and false
)42
and -0.5
)[1,3,5,9]
- see Arrays for more details.)"Hello"
and "\n"
- see Strings.){"x":10, "y":15}
- see Tables.{it*it}
- see Blocks.)Bool
, or String.Array
- types are first-class values in Swym. See Types.)In Swym, an array looks much like one in Javascript. You just write a series of values, separated by commas, between square brackets. If you want you can also put a comma after the last item; or not. (Again, this is just an aesthetic choice). And naturally, []
is the empty array. (Or [,]
or [,,,,]
.)
Note that in Swym, square brackets always denote that a new array is being created. You don't write array[0]
when you want the first element: just write array.1st
. (and similarly .2nd
, .3rd
, .53499th
, .last
, .2ndLast
and so on). Alternatively, to access elements of the array by index, you can write array.at(idx)
. (The first element has index 0).
Arrays are arguably the most important data type in Swym - essentially, whenever you're working with a collection of multiple pieces of data, you probably want them to be in an array. To a large extent, this is because there's such a rich suite of functions for working with them. For example:
I guess I had better explain a bit there. sortBy
is a function that takes two arguments - an array and a block - and returns the contents of the array, sorted by the results produced when applying that block to them. We haven't looked at blocks yet, but briefly, {.2nd}
is an abbreviation for 'it'->{ it.2nd }
- in other words, it's a function that takes an array, and returns the second element of the array. Net result: the array is sorted by the second value in each pair.
Wanna see some of the predefined functions that work on arrays?
| foo.length | The number of values in foo. |
| foo.keys | A new array: all the valid indexes into foo. (for example, [1,3,5].keys is [0,1,2].) |
| foo.random | Any value from foo, selected at (pseudo)random. |
| foo.tail | A new array: all values in foo except the first. |
| foo.middle | A new array: all values in foo except the first and last. |
| foo.stem | A new array: all values in foo except the last. |
| foo.distinct | A new array: the values from foo, but without any duplicate values. |
| foo.first(n) | A new array: the first n elements of foo. |
| foo.last(n) | A new array: the last n elements of foo. |
| foo.total | (on an array of numbers) All those numbers, added together. |
| foo.flatten | (on an array of arrays) All those arrays, concatenated together. |
| foo.slice(first=i, length=n) | A new array: n elements from foo, starting at index i. (Or fewer elements, if foo is too short.) |
| foo.slice(first=i, last=j) | A new array: elements from foo, starting at index i and ending at index j. |
| foo.slice(first=i, break=j) | A new array: elements from foo, starting at index i and ending before index j. |
| foo.splitAt(idx) | A new array containing two halves of foo - the first containing values before index idx; and the second containing values from idx onward. |
| foo.splitAt(array) | A new array containing foo cut into slices - split at each index in the array. |
| foo.splitWhere{b} | A new array containing slices of foo, split at each value for which b returns true. |
| foo.firstWhere{b} | The first value in foo for which b returns true. |
| foo.lastWhere{b} | The last value in foo for which b returns true. |
| foo.where{b} | A new array: all values in foo for which b returns true. |
| foo.min | The smallest value in foo. (Or if several are equally small, the first of them.) |
| foo.min{b} | The value in foo for which b returns the smallest value. (Or if several are equally small, the first of them.) |
| foo.whereMin | A new array: all the equal-smallest values in foo. |
| foo.whereMin{b} | A new array: all the values in foo for which b returns the equal-smallest value. |
| foo.reverse | A new array: the contents of foo, in reversed order. |
| foo.shuffle | A new array: the contents of foo, in a random order. |
| foo.sort | A new array: the contents of foo, in ascending order. |
| foo.sortBy{b} | A new array: the contents of foo, sorted by the values returned by b. |
| foo.each{b} | A new array: the result of calling b on each element. |
| foo.some{b} | True if b returns true for some element; otherwise, false. |
| foo.all{b} | True if b returns true for all elements; otherwise, false. |
Heck, I'm just scratching the surface here. Check out the Swym standard library, Stdlyb, for full details and implementations.
Strings are a special case of arrays. Any function that operates on a generic array can also operate on strings:
All right, you may ask - what do you get if you take the .1st
element of a string? Well, it's another string! Swym has no separate "character" type; it's strings all the way down. Every string is an array of strings, and each of those is an array of strings, and so on. Don't worry, you'll be fine - just take care when doing depth-first searches.
Swym supports string interpolation, as seen in Perl or Ruby: when you write $name
in a string, you're inserting the contents of the value called name
at that point. If you actually want a $ sign in your string, use \$
.
Unlike Perl or Ruby, however, Swym also lets you write $foo.bar
to call a postfix-style function within a string - or $(
whatever)
to run some arbitrary code. The latter is also useful to precisely mark the end of the interpolated section - for example, without it you couldn't insert a value that's immediately followed by a letter. "You're on the $(floor)th floor."
.
If you're printing values for debugging purposes, you may want to use the debug tostring operator $$
, instead of the terse tostring operator $
. As far as possible, the debug operator generates Swym source code that would construct the given value - whereas the terse operator generates shorter output. For example:
By the way, I'm calling them operators because they're not limited to string interpolations. $ and $$ are standalone prefix operators that you can use anywhere in your program:
By the way, notice that when Swym automatically outputs values, as above, it uses the debug tostring mode. Whereas if you print something using the print
function, it will use the terse tostring operator - that's because print is, in fact, defined in the Swym standard library as:
Anything.'print' = output($this)
...where output
is a built-in native function that takes a string (but only a string) and simply outputs it. And while we're on the subject, here's another useful function to know about, from the Swym standard library:
Anything.'trace' = output("$$this\n")
That's the debug version of println.
Take it away, maestro...
This example will hopefully give you a bit more of a feel for the language. I won't explain every detail for now, but the basic logic should be clear enough: first we're defining a function called bottles
, which takes an Int
as a parameter (implicitly named this
), and uses the function case
to choose one of three possible templates to display that number of bottles. Then, to print each verse, we count down from 99 to 1, calling it.bottles
each time to fill in the appropriate numbers of bottles.
All right, so where did "it" come from? I guess it's high time we talked about blocks. We've used several of them in the last few examples, without really explaining them. Blocks are Swym's lambda functions - in other words, first-class function values.
The notation for declaring blocks is very minimalist: just write any expression in curly brackets. A block declared this way will implicitly take one argument, called it
, and return the result of evaluating the expression. So {it*2}
, for example, is a function that just doubles the number you pass to it.
To store a block for later use, you can simply assign it to a variable - like any other value.
Oh, and notice the last line there - writing 44.myblock
is not valid! We haven't declared a function named myblock
here - we've just named a value. To actually do something, we need to call a function - in this case, the do
function. In Swym, functions have their own namespace, separate from values. In other words, it's fine to define a value named half
, and a function named half
: they'll coexist peacefully.
This system has some interesting consequences - the biggest one being that you cannot directly refer to a function, except by calling it. Blocks are first-class values that can be passed as arguments, returned, stored, printed, etc; but functions cannot. The only thing you can do with functions is to call them. This is pretty unusual in a functional language, but as it turns out, blocks are plenty powerful enough. If you want pass a function (say, println
) as an argument to another function, you would instead define a block which calls your function (say, {.println}
), and pass that.
As you can perhaps see, although Swym could certainly (semantically speaking) be classed as a functional language, it gently discourages the kind of mind-bogglingly abstract function-munging that sometimes goes on in languages like Haskell.
And now for something completely different (different from every other language, that is). In most languages, an expression must return one and only one value. In Swym, an expression can return several values!
So, er, what does that mean? Well, one common use for it is to fill in the contents of an array. If you write a multi-valued expression in an array, the result will be an array with all those values inserted at that position.
This is demonstrating two of the simplest multi-value operators.
The ..
operator returns a sequence of integers - starting with the left hand one, and ending with the right hand one. The sequence can be ascending or descending, and will include both endpoints. If you want a sequence that excludes one or both endpoints, and/or enforces an ascending or descending order, there are some related operators: ..<
for example, which will exclude the right hand number - and also the left hand one, if it's greater than or equal to the right hand side. So 1..<0
, for example, won't return any values at all. Other operators in the family are ..> <.. >.. <..< >..>
.
And of course, we're already familiar with the simplest multi-value operator: the ,
operator just returns the value(s) from its left hand side, followed by the value(s) from its right hand side.
One particularly useful way of producing multiple values is the each
function. (That's the one-argument form - not the two-argument form that we've already seen.) each
takes a list, and literally returns each element of that list. It's the inverse of the array construction []
operator. For example:
This is a little more involved, so let's go through it step by step.
The first line is a function that takes a number, and generates a list of its nontrivial divisors (i.e. the numbers it's divisible by, except for 1 and itself). So for example, nontrivialDivisors~of~16
would return [2,4,8]
. The function works by first generating an array [1<..this/2]
, which contains every positive integer greater than 1, up to and including half of the number in question (a little optimization there). Then, it calls where
to discard those which don't divide into the first number with remainder zero.
In particular, notice the code this%it
- where this
is the number we're generating the divisors for, and it
is the list element we want to test.
The second line is a function that generates a list of all divisors for a number, both trivial and nontrivial. It does this by simply constructing a list containing 1, then (literally) each nontrivial divisor, and then the number itself. And finally, the third line calls divisors
to generate all the numbers 16 is divisible by.
So, we've seen how a multi-value expression behaves within square brackets. Let's have a look at how they interact with other expressions. For example:
Yes, writing 10 + (1..6) is like writing 10+1, 10+2, 10+3, 10+4, 10+5, 10+6. Basically, the whole expression 10+(something)
is being evaluated once for each (something). If there are two or more multi-values, we run the expression once for each pair of values - each value on the left gets combined with each value on the right:
Functions and string interpolations also work this way. For example, here we call println
repeatedly:
There's an important corollary to this: when you're writing code for the body of a function, the function parameters it receives are guaranteed to be single values. If someone does call your function with a multivalue, the function body will just run multiple times.
Oh, and there's one function which gets called this way an awful lot. We saw it in the bottles of beer example - it's called for
.
The last concept I want to introduce here is called no values. It follows fairly obviously from the features I just explained: if an expression can evaluate to more than one value, naturally it can also evaluate to less than one. each[5,6,7]
returns three values, while each[]
returns no values.
Similarly, if you write print(each[5,6,7])
, the print function gets called three times. And if you write print(each[])
, the print function doesn't get called at all.
Enter the operator ?
. It takes any number of values, and drops any that are false
or null
. So null?
will return zero values, just like each[]
.
This turns out to be great for aborting a series of function calls that might fail at any point:
ApronPocket: [bob?.mother?.apron?.pocket?];
That is to say: if bob exists, get his mother; if his mother exists, get her apron; if her apron exists, get its pocket. But if any of these is null
, don't call any more functions: ApronPocket will just become []
.
In fact, ?
acts as the language's primitive building block for all conditionals. The if
function can be trivially defined using ?
:
Ta-daa! In Swym, if
is just a normal function. It takes a value and a function, and calls the function if and only if the value is truthy.
Note that if the value is falsy, if
returns zero values. This is pretty handy, as it turns out, because we can detect the difference with...
After all, how silly would it look to have an "if" without allowing an "else"?
else
is a keyword. (One of a very select set, in fact, because the language only has three keywords - is
, else
, and etc
). On its left hand side, else
takes any number of values. If there's one or more of them, it returns those values unchanged. If there are zero values, it evaluates and returns its right hand side instead.
(As is probably becoming clear, Swym is a C-like language that's built out of lego bricks.)
One last thing to note - a? else{b}
is a handy way to express a "fallback" in the event that a
is null. But there's no easy way to emulate an a?b:c operator this way. You'll just have to say if(a){b}else{c}
.
Ok - on to Swym's support for mutable data. As we already established, most of the time when you declare something in Swym, it's a constant. Here's an example of declaring a variable, modifying it, and reading from it:
Also like C, variables in Swym get passed by value. In other words, when you pass a variable into a function, its "variableness" will be stripped off. This prevents functions from unexpectedly modifying your variables. To prevent this behaviour, you can wrap the variable using the ref
function.
I think etc
is probably the part of Swym that I'm most proud of. It's the ultimate embodiment of language's design philosophy: code readability, at the cost of all else. Writing etc
in an expression is your way of telling the compiler "...and so on in the obvious way. You figure it out". Let's have a look:
There isn't all that much for the compiler to figure out, here... but we can already start to get a hint of how powerful this concept can be. The etc
keyword must appear immediately after an infix operator, and it searches the surrounding code for a chain of instances of that operator, and the arguments they take. In this case it sees the +
operator, and two arguments: .1st
and .2nd
. From these it can extrapolate .3rd
, .4th
and so on, stopping (it helpfully deduces) when the end of the list is reached. Let's see another example:
Now we're making a sequence of ,
operators, and we have two terms to extrapolate from - [.1st, .2nd]
and [.3rd, .4th]
. What's the difference between these two expressions? Well, .1st
has been replaced with .3rd
, and .2nd
has been replaced with .4th
. The compiler considers each of these differences independently. So for the first case it will deduce the sequence .1st .3rd .5th .7th...
, and for the second, .2nd .4th .6th .8th...
.

Also note the halt condition, which - of course - is reminiscent of the 1..<10 notation we saw earlier. An etc..<
expression will terminate as soon as it sees a term that's greater than the termination value. Note that while the left hand side of an etc expression is handled at compile time, the termination value is determined at runtime, so you can put a runtime variable there if you want. And as you'd expect, there's a related family: etc..<= etc..> etc..>=
.
We can use this to decompose a number into powers of two -
The compiler always assumes that each entry in the sequence follows directly on from the previous one. So if you'd like your etc sequence to alternate in some way, you'll need to bracket the expressions. let the compiler deduce how each group of terms follows on from the previous group.
In the end, the compiler processes interleave
in almost exactly the same way as byPairs
- comparing the expression (a.1st, b.1st)
with the expression (a.2nd, b.2nd)
.
Here's a quick demonstration of how to define your own each
function. (This is not actually how the built-in each
function is defined, but only for efficiency reasons.) Look, there's nothing magical about it! (at least, no more magic than the rest of the language...)
And this etc concept keeps on surprising me - every time I work with it, I find something new it can do. Very cool. Here's a particularly elegant one:
And another:
I should point out here that I've capped the number of iterations to avoid having infinite loops in cases like this. At the moment, an etc
expression cannot perform more than 1000 iterations. This won't be a permanent limit - just until the compiler can be made a little smarter about detecting loop termination conditions.
The last big concept in Swym that I haven't covered yet is the Pattern. We've seen a few already - here are some of the predefined patterns that Swym offers.
| Int | Any whole number. |
| Positive | Any number greater than zero. |
| Natural | Any whole number greater than or equal to zero. |
| Num | Any number. |
| Pattern | Any pattern (function or list). |
| String | Any string. (a list that contains only characters.) |
| Function | Any function. |
| List | Any list. |
| Bool | The value true or false. |
| Value | Any number, list, pattern, function... anything. This is the most general pattern possible. |
That's right - the types we've been using are patterns. You can think of a pattern, in general, as a (potentially infinite) set of possible values. The key feature that patterns have is the ability to test whether they contain a given value, using the is
operator:
That last line was there to wake you up. A list is a kind of pattern! Specifically, it's a pattern that contains a very limited set of values - the elements of that list. Check out how Bool
is defined, for example:
Having said that... what are the more general patterns, like Value or String? Surely they can't be lists of all possible values...?
Well, hey - a function is also a kind of pattern! Specifically, a function is a pattern that contains all values for which it returns a truthy value.
We're seeing something new here: these functions are being stored under ordinary variable names. You may remember, back when I defined myfor, that I said functions have their own namespace - and that if I had called the function f
instead of .f
, that function would not have been callable. Well, that's what is happening here. UnderTen is a function that has been 'disarmed'. By storing it under a normal variable name, we've made it behave like a normal value - you can pass it around, and test it with is
, but it cannot be called unless you first copy it into a .foo
variable. (In fact, the easiest way is to call a function that will do that for you: for( x, UnderTen )
).
Let's try defining a pattern that's more than just a toy example.
Let's see how many surprises we can pack into this section. Remember the Where
function we saw earlier, that filters a list? Well, its argument is actually just a pattern:
As is probably pretty obvious at this point, 'patterns' correspond to sets in set theory. Where
is intersection, []
the empty set, and Value
the universal set. The operator |
serves as set union, and (equivalently) list concatenation. And inversion? Well, that would be the Non
function. But hey, why don't we implement our own?
You can even implement Bertrand Russell's favourite paradox if you want:
(Pop quiz: apart from Value, my introductory list contains two other patterns that aren't described by PatternNotContainingItself. Can you name them?)
And naturally, there's no way to answer whether PatternNotContainingItself is PatternNotContainingItself
. (In fact, on the current implementation that'll cause a stack overflow).
So: that's the 'what' of patterns, in a nutshell. Now I guess I'd better answer the 'why': what are these things good for? Why are they in the language? Why conflate lists with functions and treat them both as sets?
To start answering that question, here's another example.
The Pair function, applied to a pattern, is a simple enough concept - it lets you confirm that [4,5] is Pair-of-Int
, for example.
But, as I played with this concept - and others like it that we'll see in a moment - I realized it ought to be more powerful. There are lots of situations where it's really useful to be able to iterate though every possible value of a given type; and if you use Pair on such a type, it would make sense to allow you iterate through every possible pair of those values.
I soon realized that these 'enumerable types' were essentially the same as lists - and there were plenty of situations where I wanted to use a list function on an enumerable type, or vice versa, so I was having to convert data from one format to the other. Really clunky.
So I unified them. All enumerable types are lists. All lists are enumerable types. And if you call Pair on a list (rather than just a pattern), it returns another list: all possible Pairs of elements of your list.
Internally, however, this thing is smarter than your average list - it doesn't just blindly generate the list of pairs and then try to match potential candidates against every one of the possible pairs. Enumeration happens only on demand; and testing whether a given list is a Pair-of-Bool would use a completely different code-path.
Here are some more functions that produce these "smart lists":
| List.Segment | All the different contiguous segments that can be taken from this list. |
| List.Prefix | All the segments that start from the first element. |
| List.Suffix | All the segments that end with the last element. |
| List.Filter | All the different ways you could drop elements from this list. |
| List.Permutation | All the different ways to reorder this list. |
| List.Partition | All the ways to slice this list into (nonempty) pieces. |
| P.Pair | All the possible lists that contain two P's. |
| Struct{P1, P2} | A generalization of Pair: all the possible lists that contain a P1, then a P2 - or whatever other sequence you specify. |
These things are really nice to work with. Who likes anagrams?
(As you may recall, the random
function just selects one random element from a list.)
Alternatively, we can generate new nonsense words:
And usual, the next step in this process is to start defining our own! The simplest way to create a lazy-evaluated list is the LazyList
function. For example, let's define our own version of the Prefix function - which takes a list, and returns all the ways you could truncate the list.
The LazyList function takes two arguments: the length of the list we're generating, and a function that generates elements of that list, when given their index.
It also has an optional third argument: a pattern that we can use to quickly decide whether a value is in the list. This is just an optimization - if you don't provide one, testing it will still work, but it'll be much slower. It'll search through the list, checking each element to see whether it matches. The whole point of using a LazyList, though, is that it's (potentially) an incredibly long list with a definite pattern to it. Let's try defining that Pair function.
This section is just to show off some more features that are more or less working, but I'm not satisfied with their current design.
Quantifiers allow you to say what you mean using a convenient, familiar english concept. They're currently implemented as a special kind of multi-value. So you can think of the functions .some
and .every
(and their less positive brothers .no
and .notevery
) as being strange cousins to the .each
function.
Basically, this expression some(A) > every(B) is getting executed once for every possible pairing of A and B values - but stopping when a match is found. Note also that lexical order matters - so some(A) == every(B)
is quite different from every(B) == some(A)
. (The first one checks whether there's just a single value in A that's equal to all
the values in B. The second one checks whether each of the values in B is equal to some value - but not necessarily all the same value - in A).
In an ideal world, I'd like to allow .some
(but not the others) to bind the value it has matched: if(/test( result:some(A) )){ ...do something with result... }
. I also want to find a way to get rid of the resolve operator, /
- that's how you convert these multi-values into single boolean results. But it feels clumsy to me - I want them to be auto-resolved reliably enough that you almost never need to use it. I just haven't found the correct rule for when to do it.
Cells are an amazingly useful and natural concept but, again, I'm not 100% happy with them at the moment. Essentially, a cell is an element of a list that has added metadata: it knows what list it's from, and which index it was at within that list.
To get started, the Cell function is used to convert any list into a list of cells. The cells are the same as the elements of the original list, except that they respond to three extra functions: .sourceList
to get the original list, .index
to get this cell's index within that list, and .cellValue
to strip away this metadata and just return the original value.
So far, this probably sounds moderately useful, but a little clunky. Why do we use the Cell function - isn't that just a needless extra step? Why can't this information come along for free, every time we get an element from a list? Well, actually, this explicit call provides one crucial benefit: we make it possible for the programmer to specify exactly which source list he was interested in. In other words, it becomes possible to make a list that contains cells from another list.
Here, the function Where scans through the list we give it, selects the values that are greater than 115, and uses them to create a list Y. But since the input list is Cell(X)
, Y is actually a list of cells - cells whose source list is list X. Which means that when we tell the Each function to get the index of each of them, we see their index within the list X, not their index in the list Y.
I said that cells behave the same as the value they're based on... but there is one more difference:
When you use a range operator on a pair of cells, you're not getting a numeric range: you're getting a range of cells from the source list. This makes it amazingly easy and natural to manipulate slices of a list, and do all kinds of useful tricks.
Finally, I should point out you're not limited to calling the standard .sourceList
and .index
functions. If you want, you can define your own functions that operate on cells:
So, yeah, it's all really cool stuff... but the current implementation has problems. If you filter a list of cells (as we saw above), and then you use MyMiddle on the filtered list, the result will have lost its original cell metadata. MyMiddle calls Cell internally, so the cells it returns are always sourced to the filtered list! I haven't entirely figured out what I want to do about this, but I think I want some lexical scoping here. Each block of code can only have one cell list, and if you call .Cell on a list, then that's the cell list you're going to use. Any use of .index - or any other function that takes a Cell as its argument - will implicitly select that cell list.
Eagle eyed readers may have noticed that this is the first time I've used an assignment operator in this entire tutorial. Swym is powerful enough that mutable data is often unnecessary, but I'm a pragmatist: when you need it, you need it. So I added support for opt-in mutable data.
The question is, how should it work? Under the current implementation, it's a form of metadata, much like the cells we just saw. As you can see, you create new variables with the .var
function. It takes one argument, a pattern: in this case, Int
. So this variable can only contain integer values. Initially, we assign it the value 5
, which means x
can be treated almost exactly like the value 5
, but with one extra feature: you can assign it new values with the =
operator (and others like +=
or --
). ()
This seems like a pretty nice model. For example, it means you can create a list of variables, generate a new list containing some of those variables, and use that to modify the original list.
In contrast to the other features in this section, I haven't really found a reason to call this "flawed" - it's just an area for future development. Sometimes, Saying What You Mean has to involve mutable data, because that's just What You Mean.
Ok, well... th-th-that's all I have for now, folks! Hope you enjoyed it!


Lorem ipsum dolor sit amet.
A Simple Bookmark Manager
A clean and simple interface to organize your favourite websites. Open a new browser tab and see your sites load instantly. Try it for free.
A clean and simple interface to organize your favourite websites. Open a new browser tab and see your sites load instantly. Try it for free.
Our aim is to make it quick and easy for you to access your
favourite websites. Your bookmarks sync between your devices
so you can access them on the go.
Organize your bookmarks however you like.
Our powerful search feature will help you find saved sites in no time at all. No need to trawl through all of your bookmarks.
Easily share your bookmarks and collections with others. Create a shareable link that you can send at the click of a button.
We’ve got more browsers in the pipeline. Please do let us know if
you’ve got a favourite you’d like us to prioritize.
Minimum version 62
Minimum version 55
Minimum version 46
Here are some of our FAQs. If you have any other questions
you’d like answered please feel free to email us.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce tincidunt justo eget ultricies fringilla. Phasellus blandit ipsum quis quam ornare mattis.
Vivamus luctus eros aliquet convallis ultricies. Mauris augue massa, ultricies non ligula. Suspendisse imperdiet. Vivamus luctus eros aliquet convallis ultricies. Mauris augue massa, ultricies non ligula. Suspendisse imperdie tVivamus luctus eros aliquet convallis ultricies. Mauris augue massa, ultricies non ligula. Suspendisse imperdiet.
Sed consectetur quam id neque fermentum accumsan. Praesent luctus vestibulum dolor, ut condimentum urna vulputate eget. Cras in ligula quis est pharetra mattis sit amet pharetra purus. Sed sollicitudin ex et ultricies bibendum.
Integer condimentum ipsum id imperdiet finibus. Vivamus in placerat mi, at euismod dui. Aliquam vitae neque eget nisl gravida pellentesque non ut velit.
35,000+ already joined


The Madison Chapter of the UW CS Alumni Club is here to connect Badger CS grads living in Greater Madison to each other and to UW Madison. Events were paused during Covid, but we're aiming to bring them back later this year.
The club is seeking volunteers to coordinate events, send out communication, help with the website, etc. Please send us an email here if you're interested in helping out with the Club in any capacity.


Instructions:
- Take a square piece of paper and hold it so one point points down.
- Fold it in half from top to bottom and hold it so it looks like a triangle pointing left.
- Cut off the left corner and top corner.
- Cut off the new top right corner.
- Unfold.
|


org.opencv.features2d
Class Features2d
java.lang.Object
org.opencv.features2d.Features2d
public class Features2d
- extends java.lang.Object
|
Method Summary |
static void |
drawKeypoints(Mat image,
MatOfKeyPoint keypoints,
Mat outImage)
|
static void |
drawKeypoints(Mat image,
MatOfKeyPoint keypoints,
Mat outImage,
Scalar color,
int flags)
|
static void |
drawMatches(Mat img1,
MatOfKeyPoint keypoints1,
Mat img2,
MatOfKeyPoint keypoints2,
MatOfDMatch matches1to2,
Mat outImg)
|
static void |
drawMatches(Mat img1,
MatOfKeyPoint keypoints1,
Mat img2,
MatOfKeyPoint keypoints2,
MatOfDMatch matches1to2,
Mat outImg,
Scalar matchColor,
Scalar singlePointColor,
MatOfByte matchesMask,
int flags)
|
static void |
drawMatches2(Mat img1,
MatOfKeyPoint keypoints1,
Mat img2,
MatOfKeyPoint keypoints2,
java.util.List<MatOfDMatch> matches1to2,
Mat outImg)
|
static void |
drawMatches2(Mat img1,
MatOfKeyPoint keypoints1,
Mat img2,
MatOfKeyPoint keypoints2,
java.util.List<MatOfDMatch> matches1to2,
Mat outImg,
Scalar matchColor,
Scalar singlePointColor,
java.util.List<MatOfByte> matchesMask,
int flags)
|
| Methods inherited from class java.lang.Object |
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
DRAW_OVER_OUTIMG
public static final int DRAW_OVER_OUTIMG
- See Also:
- Constant Field Values
DRAW_RICH_KEYPOINTS
public static final int DRAW_RICH_KEYPOINTS
- See Also:
- Constant Field Values
NOT_DRAW_SINGLE_POINTS
public static final int NOT_DRAW_SINGLE_POINTS
- See Also:
- Constant Field Values
Features2d
public Features2d()
drawKeypoints
public static void drawKeypoints(Mat image,
MatOfKeyPoint keypoints,
Mat outImage)
drawKeypoints
public static void drawKeypoints(Mat image,
MatOfKeyPoint keypoints,
Mat outImage,
Scalar color,
int flags)
drawMatches
public static void drawMatches(Mat img1,
MatOfKeyPoint keypoints1,
Mat img2,
MatOfKeyPoint keypoints2,
MatOfDMatch matches1to2,
Mat outImg)
drawMatches
public static void drawMatches(Mat img1,
MatOfKeyPoint keypoints1,
Mat img2,
MatOfKeyPoint keypoints2,
MatOfDMatch matches1to2,
Mat outImg,
Scalar matchColor,
Scalar singlePointColor,
MatOfByte matchesMask,
int flags)
drawMatches2
public static void drawMatches2(Mat img1,
MatOfKeyPoint keypoints1,
Mat img2,
MatOfKeyPoint keypoints2,
java.util.List<MatOfDMatch> matches1to2,
Mat outImg)
drawMatches2
public static void drawMatches2(Mat img1,
MatOfKeyPoint keypoints1,
Mat img2,
MatOfKeyPoint keypoints2,
java.util.List<MatOfDMatch> matches1to2,
Mat outImg,
Scalar matchColor,
Scalar singlePointColor,
java.util.List<MatOfByte> matchesMask,
int flags)


BLE feature is not available.
Finding BLE R/C Car
Test Device
DEVICE_ID
N/A
Connecting...
Direction
Speed
命令してね
動かす
去れ


Uh Oh!
401 - Unauthorized: Access is denied due to invalid credentials.
You do not have permission to view this directory or page using the credentials that you supplied.


The Scan
structure provides C-style conversions from string
representations.
Synopsis
signature SCAN
structure Scan : SCAN
Interface
datatype fmt_item
= ATOM of Atom.atom
| LINT of LargeInt.int
| INT of Int.int
| LWORD of LargeWord.word
| WORD of Word.word
| WORD8 of Word8.word
| BOOL of bool
| CHR of char
| STR of string
| REAL of Real.real
| LREAL of LargeReal.real
| LEFT of (int * fmt_item)
| RIGHT of (int * fmt_item)
exception BadFormat
val sscanf : string -> string -> fmt_item list option
val scanf : string -> (char, 'a) StringCvt.reader
-> (fmt_item list, 'a) StringCvt.reader
Description
datatype fmt_item
-
This datatype, which is the same type as
Format.fmt_item
, is used as a union type to represent the results of scanning input.LINT n
-
wraps a large integer value
n
to convert (the conversion specifier must be one of “d”, “o”, “x”, or “X”). INT n
-
wraps a default integer value
n
to convert (the conversion specifier must be one of “d”, “o”, “x”, or “X”). BOOL b
-
wraps a Boolean value
b
to convert (the conversion specifier must be “b”). CHR c
-
wraps a character value (the conversion specifier must be “c”).
STR s
-
wraps a string value
s
to convert (the conversion specifier must be “s”). The conversion is the identity; e.g.,STR "\n"
will produce a newline in the result string. REAL r
-
wraps a default real value
r
to convert (the conversion specifier must be one of “e”, “E”, “f”, “F”, “g”, or “G”). ATOM atm
-
this constructor will never be returned by
scanf
orsscanf
. LWORD w
-
this constructor will never be returned by
scanf
orsscanf
. WORD w
-
this constructor will never be returned by
scanf
orsscanf
. WORD8 w
-
this constructor will never be returned by
scanf
orsscanf
. LREAL r
-
this constructor will never be returned by
scanf
orsscanf
. LEFT _
-
this constructor will never be returned by
scanf
orsscanf
. RIGHT _
-
this constructor will never be returned by
scanf
orsscanf
.
exception BadFormat
-
This exception is raised when either
sscanf
orscanf
is applied to an ill-formed format string.
val sscanf : string → string → fmt_item list option
-
sscanf fmt s
scans the strings
using the format specifierfmt
. If successful,SOME items
is returned, where each item in theitems
list corresponds to a specified item infmt
. If the input cannot be scanned according tofmt
, thenNONE
is returned. If the format string is ill formed, then theBadFormat
exception will be raised whensscanf fmt
is evaluated.
val scanf : string → (char, 'a) StringCvt.reader → (fmt_item list, 'a) StringCvt.reader
-
sscanf fmt getc
returns a reader that scan a character stream using the format specifierfmt
. If the format string is ill formed, then theBadFormat
exception will be raised whenscanf fmt
is evaluated.
Format Strings
The sscanf and `scanf
functions take a format string as their first
argument. The format string is composed of zero or more
directives, which are either ordinary characters (excluding %
)
or conversion specifiers. The result of applying one of the scan functions
to an input will be a list of fmt_item
corresponding
to the conversion specifiers in the format string. All conversions are
introduced by the %
character. The format string may also contain
other characters. White space (such as blanks, tabs, or newlines) in the format
string match any amount of white space, including none, in the input. Everything
else matches only itself. Scanning stops when an input character does not match
such a format character. Scanning also stops when an input conversion cannot be
made (see below).
To be written


-
SelfCare
-
Amazing Graphs
-
Grab
-
Codar
-
Get Coffee
-
Profile Component
-
Huddle landing page with a single introductory section
-
Intro component with sign-up form
-
FAQ accordion card
-
Testimonials grid section
-
WorkPlin
-
Fylo dark theme landing page
-
Clipboard landing page
-
Fylo landing page with two column layout
-
Huddle landing page with alternating feature blocks
-
Huddle landing page with curved sections
-
Easybank landing page