« first day (420 days earlier)      last day (2221 days later) » 

11:39 AM
Join Adam tonight at 18:30 UTC for another Informal APL learning session in The APL Orchard https://chat.stackexchange.com/rooms/52405/apl See https://chat.stackexchange.com/transcript/message/41299896 … … … if you don't have 20 Stack Exchange rep points
 
 
3 hours later…
3:04 PM
@Adám Have you ever used ELI?
 
@Pavel No, but I've read some documentation there and was confused about how the interpreter disambiguates certain character sequences.
 
I'm mostly confused about how to define lparm and rparm for the compiler
I just want a Hello, World I can pass into ecc
 
@Pavel Sorry, I have no idea what you are speaking about. I'm the wrong guy for that.
 
@Adám Alright. Yeah, me neither. All I can tell is that it's complaining about lparm not defined.
 
@Pavel looks like APL with too many bytes ಠ_ಠ
 
3:36 PM
@J.Sallé As far as I can tell it's like if you wanted an ASCII APL and made a practical language and not a horrible abomination.
You can still use APL characters for stuff, but it provides ASCII alternatives
 
@Pavel ah, I see
I didn't notice you could use APL squiggles
 
Yeah, it's a superset of APL.
 
@Pavel Oh, I didn't realise that either. Where does it say?
@Pavel APL+ used to (maybe still does – no free version) have a mode that allowed English keywords for symbols.
 
@Adám On the Wikipedia article
 
@Pavel Where on it?
@Pavel Btw, Dyalog APL really should have its own page on Wikipedia. It is way more distinct from ISO APL than APLX.
 
3:53 PM
@Adám Actually, I don't remember. I'll try to find it again but I'm in class right now
 
 
1 hour later…
4:57 PM
It's Joseph Fourier's birthday today. To celebrate, here's a Discrete Fourier transform (https://en.wikipedia.org/wiki/Discrete_Fourier_transform) in APL: {⍵+.×⍨*(○0J¯2÷≢⍵)×∘.×⍨⍳≢⍵} #onelinerwednesday Try it out at tryapl: http://tryapl.org/?a=DFT%u2190%20%7B%u2375+.%D7%u2368*%28%u25CB0J%AF2%F7%u2262%u2375%29%D7%u2218.%D7%u2368%u2373%u2262%u2375%7D%20%u22C4%20DFT%20%3F7%u2374100&run
 
 
1 hour later…
6:17 PM
@Adám uh, is there really a cultivation to be?
I thought they were done for now...
 
@EriktheOutgolfer What? Yes.
 
Yeeeeeeeeee let's do it! What's it for today?
 
@EriktheOutgolfer It has been scheduled.
 
@Adám and the topic would be...?
 
@EriktheOutgolfer To be determined…
@EriktheOutgolfer Any ideas? We spoke about programming style and techniques.
 
6:21 PM
I'm all for style, techs and golfing.
 
@Adám uh, have we done file handling and such? I'm a bit unclear on those, that's why I mention it
 
@EriktheOutgolfer Lesson 13 (about half way down).
 
@Adám lol last lesson before Survivor Greece 6 started coming into the way
 
Welcome to the APL Cultivation!
So, we've covered all the building blocks you'll use to build your APL program.
Now we have to figure out how to actually write some APL programs.
When I start on a new project, the first thing I have to decide is how this code should be used.
It could be a small monolithic application. For that I'd use a single tradfn.
It could be a collection of small computation tools. For that I'd make a namespace of tacit functions and one-liner dfns.
Of course, it could be a large application too. Then a collection of classes might be in place.
Other than a bootstrapping program, I'd strive to keep things rather functional. Everything (tradfns too) should take at least one argument and return a result, and should not use global variables.
 
@Adám that should be implied...
> should not use global variables
 
6:36 PM
@EriktheOutgolfer You'd be surprised what people write… A bunch of non-result, niladic tradfns.
 
I'd like to know how can I initialize a separate workspace to work in a specific project. Up until now, I've only ever started the REPL environment to try and solve challenges, but how can I actually begin a project? When I save a workspace, does it save as a workspace file? Does each class have its own file?
 
@J.Sallé OK, let's address that.
 
@Adám that's the worst sin one can ever commit while programming! not sure as to if they ever managed to write code which adds two numbers
 
Actually, these days, I'd recommend developing in a CLEAR WS (what you get when you just start APL).
@J.Sallé I'd write )ed ○myclass and populate the skeleton the editor provides.
 
You all take "not using global variables" for granted, but if the application is a model of something based on a bunch of matrices containing parameter tables, historical data and assumptions, treating a collection of matrices as an "in memory database" is quite a rational thing to do. Excel wouldn't be a very nice tool if you couldn't refer to all the cells, but had to write code that passed things as arguments :-)
 
6:39 PM
Then I'd type ]save myclass /path/ which would create a myclass.dyalog file.
Every time I would close the editor after editing myclass, the changes would automatically be written back to file.
 
Also, performance. It's faster to change state a lot of the time. The analogy I've heard is that it's easier to move a pebble an inch than to create a new universe where the pebble is moved over an inch.
 
@Adám so you only need to do ]save once?
 
(you'd still want to write as much code in a functional style as you possibly can)
 
@MortenKromberg just because we use Excel as a programming language here at PPCG doesn't mean it's actually intended to be a programming language :P it's a tool for spreadsheet presentation, and it actually does a good job with copy-pasting
 
@J.Sallé Yes. Then the editor will make sure to save all changes. But note: only the editor. assignments and ⎕FX and ⎕FIX will not update the files.
 
6:43 PM
@Adám okay, I get it.
 
Btw, for purely functional tasks, I'd go with a dfn.
 
And the dfns are saved to the workspace, right? How do I save that?
 
In general, I like being able to see all my code at once, so I'll use a scripted namespace to keep my code in.
@J.Sallé Don't worry about the workspace. You can do ]save mydfn /path/ too.
 
ah, okay
 
@Adám what would you do for a task that even though requires only one function requires the function to be very complex?
wouldn't a dfn grow towards infinity?
 
6:46 PM
So I'd begin with )ed ⍟myproject which creates a template for the scripted namespace. Then I'd do ]save myproject /path/, and subsequent edits to the script will be auto-saved.
@EriktheOutgolfer That is very rarely needed in APL. I'd split well-defined parts of the code (i.e. parts that take some variables as arguments and returns a usable result without the intermediary values being needed other places) into sub-functions.
Of course, each programmer has his style, but I like having my functions fit on screen.
 
@Adám unfortunately, with finite space you can only represent so many functions at once :)
 
And I'd group functions into collections (i.e. namespaces) based on their category.
@EriktheOutgolfer But each carefully named sub-function can fit on a screen.
 
@Adám oh like the webpage of dfns (not actual dfns) presents?
 
@EriktheOutgolfer Yes.
 
@Adám could you give a simple example of what that namespace would look like?
 
6:51 PM
@J.Sallé Sure. Give me a min to find a good example.
 
Thanks :D
 
Not sure if this is useful but I'm working on a project where existing Python code is being converted into APL. There is an apl and a python sub-folder below github.com/romilly/breadboarder/tree/master/src. The APL is only partially complete, we're halfway through the conversion exercise.
 
So I have a class which says :Include #.MS3SiteUtils and that includes all the functions from the utility namespace into the class.
I didn't want to have to "dot" into sub-namespaces, but there were too many utility functions to just bunch them all together. Therefore, I used :Section to split the namespace. This allowed me to use the editor's tree-view to navigate.
 
@Adám and I assume you can import a specific section?
 
6:58 PM
You'll notice that most functions fit on about page. I use plenty of whitespace and every function needs at least a comment saying what it does.
@J.Sallé No. Sections are only for the human.
 
@Adám sections D, E and F look pretty longer than that to me (1366x768)
 
@EriktheOutgolfer Sections are not functions.
 
In case anyone is interested: To load the APL code, after a git checkout, I would type
]load C:\Devt\breadboarder\src\apl\*
In versions <17.0 which is as yet unreleased, you will need to do that twice because a few of the source files will fail to load due to missing base classes. The second time, the base classses are define (in v17.0 we allow classes to be fixed even if dependencies are missing).
 
@EriktheOutgolfer The longest function in section D is 12 lines.
 
@Adám I mean between :SECTION and :ENDSECTION, not functions
 
7:00 PM
@Adám oh, okay.
 
oh wait you said functions
 
To exercise it, call TestDrawBreadBoard, which creates the same svg that the python test case has previously created and compares it.
 
@EriktheOutgolfer Sure. As you said, sometimes we need a lot of code. So break the code into tiny bits.
 
Damn, I gotta go now, my boss just called a meeting. I'll catch up when I'm done there. Thanks for the tips guys, I'll be sure to use them :D
 
I tend to reserve an area (a section or namespace) for small general purpose utilities, like string splitting (≠⊆⊢) and maybe "if" ({⍺←⊢ ⋄ ⍺⍺⍣(⍵⍵ ⍵)⊢⍵}).
For now, let's not worry about golfing.
 
7:07 PM
Sure
 
Clearly, this is a "utility" function. So I'd go with a single tradfn or dfn.
 
@Adám you won't believe how hard I discourage spoiling yourself over Jelly HyperTraining...
 
@EriktheOutgolfer Spoiling myself?
 
@Adám who knows who has posted an APL answer over there...
 
@EriktheOutgolfer Nobody has.
So I'd begin a new function )ed Scramble and probably begin it as a tradfn. We can always convert it to a dfn or tacit fn later.
Obviously we're looking for specific patterns (word), but preferring APL over regex, I'd want to minimise the regex usage.
So I'll outline my function like this:
text←Scramble text

text←'\pL+' ⎕R something ⊢ text
The regex part just finds the words, and then we need to find "something" that can process each word as needed (we'll define that on the empty line).
 
7:13 PM
@Adám what does '\pL+' match?
 
@H.PWiz That's Perl regex for one or more characters of the Letter class.
 
Okay. I'm used to '\w+'
 
@H.PWiz Yeah, but that'll match abd234 too.
 
So what are we doing with strings like abcd234?
rearranging the letter bit, or leaving it?
 
@H.PWiz Scramble the abcd part.
Then I'll define a dfn that just expects a single word as its argument.
We know that we do not move the first and last letters, so lets begin by removing those:
something←{
middle←1↓¯1↓⍵.Match
⍵.Match is just the matched text as the argument to ⎕R's operand is a namespace.
Now we need to classify the characters into the four groups.
So we need to a membership between each letter and the groups. One way we can do that is with an outer product:
⎕←'hi ppcg'∘.∊'bdfhkl' 'acemnorsuvwxz' 'gpqy' 'it'
 
7:23 PM
@Adám
1 0 0 0
0 0 0 1
0 0 0 0
0 0 1 0
0 0 1 0
0 1 0 0
0 0 1 0
 
@Adám lol my OCD shouts "DO ⍸¨↓ DAMMIT"
 
@EriktheOutgolfer Nope, let's do real multi-dimensional arrays.
So on each row, we need to find the index of the one.
 
@Adám I know, that's why I don't listen to my OCD
 
So we need the "find-first-one" function. For such a simple thing, I'd go tacit:
⎕←0 0 1 0⍳1 ⋄ ⎕←(⍳∘1)0 0 1 0
 
@Adám
3
3
 
7:28 PM
And on each row is ⍤1 (on each array of rank 1, i.e. vector, i.e. row):
⍞←⍳∘1⍤1⊢'hippcg'∘.∊'bdfhkl' 'acemnorsuvwxz' 'gpqy' 'it'
 
@Adám 1 4 3 3 2 3
 
Now we have:
text←Scramble text
something←{
middle←1↓¯1↓⍵.Match
FirstOne←⍳∘1
Rowwise←⍤1
Classify←∘.∊∘'bdfhkl' 'acemnorsuvwxz' 'gpqy' 'it'
FirstOne Rowwise Classify middle

text←'\pL+' ⎕R something ⊢ text
 
@Adám missing a }?
 
@H.PWiz We're just programming, this isn't runnable at all yet.
 
Oh, my bad
 
7:34 PM
tbf it does look like somebody pressed Shift+Enter instead of Shift+] though...keys next to each other
 
@EriktheOutgolfer Oh, right :-D
We can use a construct like @(⍵=type)⊢text}¨type to process each type and do something to the collection of characters that have that type.
What we need to do is to shuffle. So I'd make a small utility function that shuffles its argument.
 
@Adám what is type
 
@Adám Using ?⍨ I presume
 
@EriktheOutgolfer the class it belongs in of 'bdfhkl' 'acemnorsuvwxz' 'gpqy' 'it'. Sorry for inconsistent terminology.
@H.PWiz Yes:
⍞←{⍵[?⍨≢⍵]}'abcdef'
 
@Adám dcbafe
 
7:38 PM
So I'd define that as Shuffle←{⍵[?⍨≢⍵]}.
I think {text⊢←Shuffle@(⍸⍵=type)⊢text}¨type will work.
 
@Adám What exactly does ⊢← do? Also ∘← and similar others
 
@Adám wow didn't know @ does that
 
@H.PWiz ⊢← is modified assignment, like += in many languages. ∘← is an unintentional quirk and shouldn't be relied on.
@H.PWiz Here, I'm (ab)using that modified assignment is in-place and so the dfn doesn't localise text.
Because I really want the side-effect of the helper dfn, which is not really the purpose of dfns, but it sure works here ;-)
 
@Adám Okay, and a f←b is a ← a f b?
 
@H.PWiz Yes.
So now we have:
 text←Scramble text
 something←{
     middle←1↓¯1↓⍵.Match
     FirstOne←⍳∘1
     Rowwise←⍤1
     Classify←∘.∊∘'bdfhkl' 'acemnorsuvwxz' 'gpqy' 'it'
     type←FirstOne Rowwise Classify middle
     Shuffle←{⍵[?⍨≢⍵]}
     text⊣{text⊢←Shuffle@(⍸⍵=type)⊢text}¨type
 }
 text←'\pL+'⎕R something text
 
7:45 PM
@Adám lol can't you just use /
 
@EriktheOutgolfer Sure, you could do that too:
 text←Scramble text
 something←{
     middle←1↓¯1↓⍵.Match
     FirstOne←⍳∘1
     Rowwise←⍤1
     Classify←∘.∊∘'bdfhkl' 'acemnorsuvwxz' 'gpqy' 'it'
     type←FirstOne Rowwise Classify middle
     Shuffle←{⍵[?⍨≢⍵]}
     text⊣{mask←⍵=type ⋄ ⊢(mask/text)←Shuffle mask/text}¨type
 }
 text←'\pL+'⎕R something text
But really @ is just a shortcut for doing exactly that kind of operations.
 
@Adám lol I didn't mean replicate, but avoiding the ⊢←-type assignment
like, reducing the function instead of using text and only assigning its result to it
 
I just inserted the because the function needs a result. We are really abusing a dfn.
@EriktheOutgolfer Ah, ngn style. Right.
 
@Adám actually, that looks more natural to me, maybe with the added too
 
The last step is of course to put the first and last letters back on the left and right of the result.
 
7:53 PM
@Adám heh
 
@EriktheOutgolfer Like this:
⊃{{⍵[?⍨≢⍵]}@(⍸⍵∊⍺)⊢⍵}/'bdfhkl' 'acemnorsuvwxz' 'gpqy' 'it' text
So here is a much cleaner solution using @EriktheOutgolfer's idea:
 text←Scramble text
 something←{
     middle←1↓¯1↓⍵.Match
     middle←⊃{{⍵[?⍨≢⍵]}@(⍸⍵∊⍺)⊢⍵}/'bdfhkl' 'acemnorsuvwxz' 'gpqy' 'it'middle
     (⊃⍵.Match),middle,(⊃⌽⍵.Match)
 }
 text←'\pL+'⎕R something text
 
@Adám that deviated a lot from what I thought at first...
I just meant using a reduce to remove the need for the abusive ⊢←
 
Notice that I've parenthesised (⊃⌽⍵.Match) even though it doesn't need to be. I often do this to emphasise symmetries.
When writing APL (or any language really), it is a good idea to write your code to ease reading.
OK, this has been a somewhat different type of lesson. I hope you found it useful.
 
@Adám oh yeah, and I thought I was average enough in APL
 
In this coming week, please think about what you want us to cover in the next lesson. I'll be happy to prepare material, I just need to know what about.
 
 
3 hours later…
10:55 PM
@EriktheOutgolfer I'm not sure APL has enough audience to sample averages :P
 
11:46 PM
@Adám I know (1 2 3) (4 5 6) defines a vector of vectors, how can I define a matrix?
 
@Pavel You have to use or . (or maybe some other function). AFAIK
 

« first day (420 days earlier)      last day (2221 days later) »