We should use square brackets when flattering all levels in list:
q)b:(1 2;(3 4;5 6);7;8)
q)raze/[b] / flatten all levels
1 2 3 4 5 6 7 8
q)raze/b
'/
[0] raze/b
But why one forced to use raze/[b] for Converge syntax instead of simple raze/b?
Upd
Why this syntax works in k, for example {x+y}/1 2 3 but doesn't work in q?
My assumption that it's been made to prevent qbies errors when using / adverb instead of %. I think there may be a discussion about it in some dev channel, but I've found only Shakti discussion group for now at https://groups.google.com/forum/#!forum/shaktidb, and kx.com also shutted down community wiki, so I don't know where to find an additional info - asking here
Upd2
The / is quite overloaded in k too: see (not official ref though) https://github.com/JohnEarnest/ok/blob/gh-pages/docs/Manual.md#over - over, fixedpoint, for and while. Pretty the same as in q, right? But why the interpreter 'ban' the k syntax in q context, - is there a technical reason why q can't recognise a user intention as it k does?
The reason that, say, cos/1 works in k but not q is that q has no ambivalence. That is to say that all q operators are not overloaded on valence, as noted in section 6.1.2 in q4m.
With any of q's adverbs (each:', over:/ scan:\, prior::, eachright:/:, eachleft:\:) the resulting derivative function is interpreted by q to be dyadic, unless you uses []'s to specifically pass one argument.
For the example above q interprets cos/ as do rather than converge and so requires the left argument specifying the number of iterations (Note the results of 0 cos/ 1, 1 cos/ 1, 2 cos/ 1, etc.). The preferred way to resolve is to use []'s: cos/[1].
(cos/) 1 works because user defined functions can never use infix notation, so the expression is automatically interpreted as applying monadically. This is also why 2 (cos/) 1 fails. To resolve this you would again have to use []'s: (cos/)[2;1].
You don't necessarily need square brackets here. You could use
(raze/)b
if you do not want to use square brackets around b. The way you are using over ( or /) without the brackets around b requires the parenthesis around raze/b if you do not specify the initial value of the accumulator. This is because the q interpreter needs to know that you are applying raze/ to the list b rather than applying / to the list first (which is why a '/ error is thrown) then raze after (reading the code from right to left).
More info on using / can be found here: https://code.kx.com/q4m3/6_Functions/#676-over-for-accumulation
This is a pattern of optimization in Lisp code that I want to achieve in Red:
(defmacro compute-at-compile (x)
`(+ ,(* pi 2) ,x))
(macroexpand '(compute-at-compile 1))
; => (+ 6.283185307179586 1)
How do I express this in Red? (I realize it may not be possible in today's implementation, I'm wondering about how one would express the code at the language level to get such an optimization. Would it require special markup in the source, or would it be automatic like Lisp?)
Trying to extend my answer to maybe cover another idea that may help you find what you are looking for.
Red/System
From my understanding, the Red/System #define directive can help with optimization (in reducing function calls). Here is a similar example in Red/System. Within Red, it would require using within #system or #system-globaldirective.
#define COMPUTE(x) (3.13159 * 2.0 + x)
b: COMPUTE(1.0)
print b
Processing the macro should result in:
b: (3.13159 * 2.0 + 1.0)
print b
and results
7.26318
Math between types isn't defined yet, so you'll run into issues multiplying/adding float! and integer! (hence the above use of float!)
Red/Rebol
You can also take a look at compose as a higher level way to optimize your code writing. I am unsure of the effect in terms of optimizing speed. What compose does is take a block and evaluate whatever is in parenthesis and not evaluate other elements in the block.
See the Rebol2 help definition for compose
>> help compose
USAGE:
COMPOSE value /deep /only
DESCRIPTION:
Evaluates a block of expressions, only evaluating parens, and returns a block.
COMPOSE is a native value.
ARGUMENTS:
value -- Block to compose (Type: any)
REFINEMENTS:
/deep -- Compose nested blocks
/only -- Inserts a block value as a block
This may be what you're looking for in terms of building expressions
red>> x: 1
== 1
red>> compose [3 + 2 + (x)]
== [3 + 2 + 1]
An example from the Rebol2 documentation:
>> probe compose [time: (now/time) date: (now/date)]
[time: 12:48:53 date: 5-Mar-2014]
== [time: 12:48:53 date: 5-Mar-2014]
I edit a lot of Scala code in Vim, which means I hit f = a lot, as I head to the RHS of a case statement (or whatever else):
case PatternMatch(a, b, c) => RHS Here
But Scala supports unicode characters, which means that a lot of people will use ⇒ instead of => and that makes f ... a pain in the butt. Does anyone know how if there's a way to make f = move to the next = or ⇒, whichever comes first?
Try adding this to your vimrc:
nmap f= :call search('=\\|⇒')<CR>
That will alias (map) f= to a call to the search function that will jump to the next = or ⇒.
bundacia's answer is the one you asked for. Another option is to use digraphs. You can type ⇒ in vim by typing <C-k>=> in insert mode. You can also use this digraph with the f command (e.g. f<C-k>=>). No need for mappings etc. though it may be somewhat inconvenient to type.
I prefer this solution since it preserves other operator pending commands such as df=, cf=, etc. and allows the use of F, t, etc.
What would be good purely functional data structures for text editors? I want to be able to insert single characters into the text and delete single characters from the text with acceptable efficiency, and I would like to be able to hold on to old versions, so I can undo changes with ease.
Should I just use a list of strings and reuse the lines that don't change from version to version?
I don't know whether this suggestion is "good" for sophisticated definitions of "good", but it's easy and fun. I often set an exercise to write the core of a text editor in Haskell, linking with rendering code that I provide. The data model is as follows.
First, I define what it is to be a cursor inside a list of x-elements, where the information available at the cursor has some type m. (The x will turn out to be Char or String.)
type Cursor x m = (Bwd x, m, [x])
This Bwd thing is just the backward "snoc-lists". I want to keep strong spatial intuitions, so I turn things around in my code, not in my head. The idea is that the stuff nearest the cursor is the most easily accessible. That's the spirit of The Zipper.
data Bwd x = B0 | Bwd x :< x deriving (Show, Eq)
I provide a gratuitous singleton type to act as a readable marker for the cursor...
data Here = Here deriving Show
...and I can thus say what it is to be somewhere in a String
type StringCursor = Cursor Char Here
Now, to represent a buffer of multiple lines, we need Strings above and below the line with the cursor, and a StringCursor in the middle, for the line we're currently editing.
type TextCursor = Cursor String StringCursor
This TextCursor type is all I use to represent the state of the edit buffer. It's a two layer zipper. I provide the students with code to render a viewport on the text in an ANSI-escape-enabled shell window, ensuring that the viewport contains the cursor. All they have to do is implement the code that updates the TextCursor in response to keystrokes.
handleKey :: Key -> TextCursor -> Maybe (Damage, TextCursor)
where handleKey should return Nothing if the keystroke is meaningless, but otherwise deliver Just an updated TextCursor and a "damage report", the latter being one of
data Damage
= NoChange -- use this if nothing at all happened
| PointChanged -- use this if you moved the cursor but kept the text
| LineChanged -- use this if you changed text only on the current line
| LotsChanged -- use this if you changed text off the current line
deriving (Show, Eq, Ord)
(If you're wondering what the difference is between returning Nothing and returning Just (NoChange, ...), consider whether you also want the editor to go beep.) The damage report tells the renderer how much work it needs to do to bring the displayed image up to date.
The Key type just gives a readable dataype representation to the possible keystrokes, abstracting away from the raw ANSI escape sequences. It's unremarkable.
I provide the students with a big clue about to go up and down with this data model by offering these pieces of kit:
deactivate :: Cursor x Here -> (Int, [x])
deactivate c = outward 0 c where
outward i (B0, Here, xs) = (i, xs)
outward i (xz :< x, Here, xs) = outward (i + 1) (xz, Here, x : xs)
The deactivate function is used to shift focus out of a Cursor, giving you an ordinary list, but telling you where the cursor was. The corresponding activate function attempts to place the cursor at a given position in a list:
activate :: (Int, [x]) -> Cursor x Here
activate (i, xs) = inward i (B0, Here, xs) where
inward _ c#(_, Here, []) = c -- we can go no further
inward 0 c = c -- we should go no further
inward i (xz, Here, x : xs) = inward (i - 1) (xz :< x, Here, xs) -- and on!
I offer the students a deliberately incorrect and incomplete definition of handleKey
handleKey :: Key -> TextCursor -> Maybe (Damage, TextCursor)
handleKey (CharKey c) (sz,
(cz, Here, cs),
ss)
= Just (LineChanged, (sz,
(cz, Here, c : cs),
ss))
handleKey _ _ = Nothing
which just handles ordinary character keystrokes but makes the text come out backwards. It's easy to see that the character c appears right of Here. I invite them to fix the bug and add functionality for the arrow keys, backspace, delete, return, and so on.
It may not be the most efficient representation ever, but it's purely functional and enables the code to conform concretely to our spatial intuitions about the text that's being edited.
A Vector[Vector[Char]] would probably be a good bet. It is an IndexedSeq so has decent update / prepend / update performance, unlike the List you mention. If you look at Performance Characteristics, it's the only immutable collection mentioned that has effective constant-time update.
We use a text zipper in Yi, a serious text editor implementation in Haskell.
The implementation of the immutable state types is described in the following,
http://publications.lib.chalmers.se/records/fulltext/local_94979.pdf
http://publications.lib.chalmers.se/records/fulltext/local_72549.pdf
and other papers.
Fingertrees
Ropes
scala.collection.immutable.IndexSeq
I'd suggest to use zippers in combination with Data.Sequence.Seq which is based on finger trees. So you could represent the current state as
data Cursor = Cursor { upLines :: Seq Line
, curLine :: CurLine
, downLines :: Seq Line }
This gives you O(1) complexity for moving cursor up/down a single line, and since splitAt and (><) (union) have both O(log(min(n1,n2))) complexity, you'll get O(log(L)) complexity for skipping L lines up/down.
You could have a similar zipper structure for CurLine to keep a sequence of character before, at and after the cursor.
Line could be something space-efficient, such as ByteString.
I've implemented a zipper for this purpose for my vty-ui library. You can take a look here:
https://github.com/jtdaugherty/vty-ui/blob/master/src/Graphics/Vty/Widgets/TextZipper.hs
The Clojure community is looking at RRB Trees (Relaxed Radix Balanced) as a persistent data strcuture for vectors of data that can be efficiently concatenated / sliced / inserted etc.
It allows concatenation, insert-at-index and split operations in O(log N) time.
I imagine a RRB Tree specialised for character data would be perfectly suited for large "editable" text data structures.
The possibilities that spring to mind are:
The "Text" type with a numerical index. It keeps text in a linked list of buffers (internal representation is UTF16), so while in theory its computational complexity is usually that of a linked list (e.g. indexing is O(n)), in practice its so much faster than a conventional linked list that you could probably just forget about the impact of n unless you are storing the whole of Wikipedia in your buffer. Try some experiments on 1 million character text to see if I'm right (something I haven't actually done, BTW).
A text zipper: store the text after the cursor in one text element, and the text before the cursor in another. To move the cursor transfer text from one side to the other.
I'm trying to pick up some scala. Reading through examples I came across this impossible-to-google nugget:
case 3 => l ::: List(3)
What does the triple colon accomplish?
Concatenates two lists - javadoc
To add to gkamal's answer, it's important to understand that methods whose names end in a colon are right-associative. So writing l ::: List(3) is the same as writing List(3).:::(l). In this case it doesn't matter since both operands are lists, but in general you'll need this knowledge to find such methods in the scaladocs.
It also helps to know that the scaladocs have a comprehensive index of all methods (and classes, etc) with symbolic names. You can reach it by clicking on the # in the upper-left corner.