You'll want to use the appropriate backend for your system, of course.
README.md
I get the "Where is Co-dfns documented?" question a lot. Is the README.md not obvious for people? Serious question. I thought that I had made things pretty easy to find.
What I'm saying is I don't know what codfns is enough to know what to do with it. I don't know what I get from codfns, it is a compiler, but does it compile to an exe? How is it used, is it used by simply having it installed, or do I need to call into it, how do I call into it aside from the gfx lib tha is mentioned
]?codfns
CODFNS:
Compile Compile an object using Co-dfns
] ⍝ for general user command help
]cmd -? ⍝ for info on the "Cmd" command or group
]?codfns.compile
───────────────────────────────────────────────────────────────────────────────
]CODFNS.Compile
Usage: <object> <target> [-af={cpu,opencl,cuda}]
@arcfide
┌───────────────────────────────────┬┬────────────────────────────────────────┬──────────────────────────────────────────────┬─────────────────────────────────────────┬─────────────────────────────────────────────────┐
│No commands or groups match ]codfns││] ⍝ for general user command help│] -? ⍝ for list of available user commands│] -?? ⍝ for brief info on each command│]cmd -? ⍝ for info on the "Cmd" command or group│
└───────────────────────────────────┴┴────────────────────────────────────────┴──────────────────────────────────────────────┴────────────────────────…
The relevant section of the README.md is: Normal use of the compiler can be accessed through the User Command functionality, and documentation for the User commands is available using the ]?codfns. There are some specific features that require you to have a copy of the Co-dfns namespace in your local workspace. These APIs are described in this section.
It's specifically targeting GPU computation though, so for many things on the CPU you probably won't see significant improvements unless you are working on the kinds of workloads the compiler is designed for.
Not exclusive, but the syntax is best implemented by Dyalog.
There's a bit of copy overhead right now, but in principle, yes, you would be able to pass Co-dfns objects residing on the GPU and be able to render them directly.
@nathanrogers, I'd be quite eager to explore such options if you can provide a sustainable funding model that will provide for continued and expanding support for the APL ecosystem into the future, including my own research agenda(s).
Also, Dyalog isn't really opposed to open source.
Co-dfns is itself Open Source, but the reality of the situation is that if I were strictly open source, Co-dfns simply wouldn't exist. The open source community at large hasn't exactly felt the need to fund such things.
I have a bit of a love/hate relationship with Open Source and the community especially, because my experience with them has lead to me to the conclusion that in practice those who derive value from Open Source often don't contribute funding back to the core community in a way that provides for a sustainable model.
The funding for open source at the moment largely comes from the support of people who are able to derive value from the markets through proprietary systems. Open source systems don't seem to be self-sustaining at the moment, particularly language implementations.
Put another way, that's a bit of an FAQ that I get and one that I would love to have a better answer to, but at the moment the Open Source community isn't willing to support Co-dfns existing in the manner they claim that it should be.
@pierre i'm learning about 2: and wondering about all i/o verbs: what's the point of using "file symbols" instead of good old strings? is there any benefit to paths being interned scalars or is it just more convenient to type?
@nathanrogers HOW many times do I have tell you, don't change the definitions! (sorry im getting a bit mad of you always doing that after me telling you to not) My question is about how to convert the single point array to an array where it's the only object.
I want b to be a single point object, such that b[1] is its X position, b[2] is its y postition, b[3] is its color. Now I want c to be an array of those points, such that c[1] is b. How do I initialize c? In dyalog that'd be c←,⊂b, but you're saying that ⊂ shouldn't exist, so how the hell would you do that?
the reason I want c to be like that is because b,←⊂1 2 'gray' would make b4 5 'red' 1 2 'gray', which I don't want, but c,←⊂1 2 'gray would be (4 5 'red') (1 2 'gray') which is what I do want
I know that that might not be the best thing to do in APL, but I just want a basic understanding of your model before I try to do anything "correctly" in it
@dzaima in a language in which everything is a vector you wouldn't need , in the dyalog sense, so maybe k's , would be more useful (like ,⊂ in dyalog)?
this idea (no scalars, only vectors) appears attractive at first, but (1)(2) ≢ 1 2 seems too inconsistent
@nathanrogers suppose you have a←1 2. you make it heterogenous with a,←(3 4)(5 6) and drop the last two elements: a↓⍨←2. what would a be then? i expect (1)(2), which is different from the original 1 2
@ngn in that example, why would appending to a list make the existing data heterogeneous? a←1 2 is a two element vector. a,←(3 4)(5 6) is a 4 element vector. 1 2 (3 4)(5 6)
if you drop the last to you still get the vector (1 2)
@Quintec I don't exactly have a problem. We were talking about RAD and I had a question about why ⊂⊃ if everything is rankless. if everything has no rank then functions could apply across lists with no need for¨ if there is no ¨ then why need scalars at all? Just have 3 "basic" types, rows, columns, and tables. Functions apply across any of these, where "scalars" are already enclosed 1 item vectors that are extended to adjacent "scalars"
@ngn think about it this way. How would I write 1 2 3 4 5 in any other langauge? [1,2,3,4,5], already in a a box so if I "enclose" something else in that list, it will have depth two 1 2 (3 4) 5 [1,2,[3,4],5]
so since everything is already a list, no need for the concept of enclosure
just drop them from the notation because it's already in a list
1 2 3 4 is the same as [1,2,3,4] in other languages from APL to C ALREADY
they're conceptually equivalent. the cognitive issue that I have is that we need extra crap to transform the data to say, no wait really this is a list.
no wait stop, this isn't a list of items, its a """""BOXED"""""" list, so now we can refer to it as the list that it already is?
@nathanrogers this makes no sense to me, but i've been wrong before, so who knows, maybe you're on to something. i think you should try to implement it
Hence my line of questioning. There's probably a whole class of problems that can't be solved, or elegantly simplified with this approach
@ngn so I'm probably oversimplifying and daydreaming. I'd like to implement something just so I can get over my mental hurdles in understanding APL. I spend most of my time finagling with different transformation on the data, unsure if its a bug in my code, my data, the language, or something else
so the eliminating the need to transform the data in all possible ways would simplify things immensely
@Adám if not for @dzaima 's awesome processing app I don't even know what problems I should be solving. Really, I feel like I'm floundering outside of using that processing app, but even then in using that app, I'll spend several hours trying to debug something, unsure if its the function, the data, the implementation, or the app... what's interesting to me, is that 90% of the time its the structure of the data being passed to the function
so there's probably some fundamental issue with how I'm structuring the data, but since I don't know APL well enough, often times I mistake tables as vector of vectors
because they're the same thing... why have the distinction at all?
why does ,0 work on each row, but other functions don't?
it would make more sense to me that functions either apply to a vector of vectors or to each cell in a table, not have special rules for one or the other
either all built-in functions apply to tables, or they apply to each vector, or they apply to each cell
@nathanrogers You need to free yourself. Don't worry — you're not alone. It is notoriously difficult for "traditional" programmers to free their minds and become APLers. Those with no programming background have a much easier time.
@nathanrogers In APL, everything is an array — even scalars.
And indeed, if you actually inspected how Dyalog uses memory, you'd see that there is no difference in how a scalar and any other array are represented.
@Adám I'll tell you what I know. The pluralized notation, thinking, operations that can be performed via abstracting away the concept of iteration and map and filter and etc is the best thing that has ever happened in the computing world. Having this notation in C++ would be better than having it as a standalone language however because of the library support and APIs available
the pluralized computation is it's own reward, and I can't fathom how I live in a branch of the universe where it wasn't universally adopted
It gets in the way of expressing what I want to do. "Notation as a tool of though" when the implementation details of your data have to be expressed, then your notation is broken
@nathanrogers Exactly, hence I wrote "you don't need to know this".
I'm just trying to convince you that there is no fundamental difference in the nature of a scalar and any other array. Free yourself from the notion and you loose one more unnecessary complication of thought.
I'm not the one who is saying there is a fundamental difference. Every big of reading I've done on APL suggests that there is a difference
there are even "scalar functions" which operate on scalars
there is no inference from the length of arguments
either scalar or matching length
which also makes no sense to me. who not infer 1 2 + 2 5 ⍴⍳ 10 that the LIST OF 1 2, which is a list, and therefore enclose, should apply accross the dimension of length 2?
@nathanrogers That concept has a name. It is called prefix agreement and J has that. Unfortunately, the powers at be have not heard my cries for the same in APL.
I've encountered several where I must pass several terms to a function, but then through mangling they wound up in a matrix because it was the least obtuse way I could figure to get all that data into the function
once there, I had to perform further mangling to separate them into their respective parts
so I ould 2 + 1 2 and 3× 3 4
but
it would have been so much nice just to leave them in the table which took me forever to figure out how to make in the first place, and just apply out accross a vector of functions
@nathanrogers Sounds like the issue was with the representation. If you need to apply different functions to parts of an array, then they don't belong in the same array.
@nathanrogers that's where I disagree - a matrix should only ever be used if in both axis the length isn't constant, otherwise its pointless to have them in a matrix
but then when each cell is actually a nested datastruture
then you have a table in each row
if you have a 2d or 3d vector of location, dimension(size), acceleration, velocity then one column is a table in and of itself
so hence a matrix
and I need to calculate the locations velocity by its own acceleartion, and draw it's own specific dimension
so I need to apply several different operations to the "matrix" at once
yes they're all column vectors, but why should I need to then break them apart to do the calcualations when most of it can be accomplished through a vector of functions
it's just adding more notation and steps to breaking apart the table
@nathanrogers Maybe you should look into tradfns which make it easy to pass multiple arguments and return multiple results. You could also pass namespaces with named arrays. Finally, you can use a single matrix, but then use indexing to easily pick the pieces you need. For ease of reading, define some names that just hold the column numbers.
@nathanrogers I do agree that the notion of prefix agreement together with arrays of functions sounds intriguing. I have not seen a language do that to be able to judge it though.
@nathanrogers a matrix is for things where both dimensions can be anything. A vector of vectors is for when there's a specific amount of collumns to deal with
@nathanrogers Correct, the scalars of a row are not comparable. Neither in a table, nor in a matrix.
E.g. when the classic matrix represents an equation system, each column represents a distinct variable, and so columns are not comparable. However, all rows have the same standing.
E.g. when a table lists countries' data, each column represents a distinct metric, and so columns are not comparable. However, all rows have the same standing.
You always (unless you're doing something really funky) sort the rows of a table, and sorting is done by comparing corresponding items in the rows — never across columns.
@EriktheOutgolfer I won't look at it tonight, but feel free to trace through it offline. Stencil is just an operator taking operands and arguments straight from TIO's fields.
@Adám what I'm mostly focusing on is how to organize my painkillers, food (yeah, eating is hard) and antibiotics, currently :P yeah, I can't look through it today
@nathanrogers Basically just a thin cover for ⌺ (hence the name Stencil). It shortens the variant option names, takes care of edge cases, and simplifies specification and usage of neighbourhoods.
(Btw, I have two other golfing languages on TIO, QuadR and QuadS, which again are just thin covers for ⎕R and ⎕S.)
This reminds me that I should add some of Stencil's features to my extended Dyalog APL.
@dzaima Think of it in the Haskell (?) sense, that application of a dyadic function is really just application of a monadic function with implied left argument.
That makes monadic and dyadic functions syntactically equivalent.
@dzaima No. Think of 6÷3 as applying the function 6∘÷ to 3.
Why isn't it applying ÷∘3 to 6? Because APL functions take the specifier (if any or if it isn't the default) as left argument, and the primary argument as right argument.
It should be clear from functions like -÷*⍟⌹○ that this is the norm.
@dzaima But it isn't. Monadic functions are prefix. However, there could be a case for an APL where monadics are post-fix, and all functions are left-associative. There, dyadic - and ÷ and * would fit right in as-is, though the monads would be fairly useless.
yeah, it breaks the idea that the monadic version of a function is the dyadic one with a default left arg, but I feel like the idea of that comes from the implementation, not the other way around
@dzaima … And that idea has been carried over in APL and became quite fundamental to how people wrote code. Did you know that in IBM's APL, the left argument of a tradfn is always optional?