« first day (1441 days earlier)      last day (1510 days later) » 
04:00 - 21:0021:00 - 00:00

21:04
yeah true I removed the explanation as I golfed it
I'll readd it in a second
No worries, I bountied another one of yours in the mean time. Feel free to remove the <i></i> when done.
it was quite hard to fit it without the scrollbar appearing
but i tried my best
Looks great.
21:33
I'd love to see an APL answer to this challenge (Golfed fixed point combinator): codegolf.stackexchange.com/q/1064/95792
⍣≡?
No, a fixed point combinator
rak1507's solution is exactly that, no? "a higher-order function fix fix that returns some fixed point of its argument function, if one exists." (Wikipedia)
> you may not use your standard library's if it has one
APL doesn't have one, luckily.
21:36
But ⍣≡ doesn't take functions (or operators, since f is a higher-order function) as arguments, does it?
If does. ⍣≡ is a tacit derived monadic operator.
idk how you'd even create a function like (haskell) \f n->if n <= 1 then 1 else n*f(n-1) in APL
@rak1507 You just did, though :)
I mean make the APL equivalent
f←{n≤1:1⋄⍵×∇⍵-1}?
21:39
Without using recursion
It's like an operator, but not quite
⍺⍺ would work, right?
Right, but I don't think that will work
f←{⍵≤1:1⋄⍵×⍺⍺⍵-1} maybe
@rak1507 you can't make a recursive function without recursion
(but you can make an iterative equivalent)
I mean without ∇
21:40
@Wezl Isn't that the whole point of fixed point combinator? Doing that?
without named recursion
The Y combinator does just that
it's still recursion, it's just not dependent on names
⋄fix←⍣≡⋄fact←{⍵≤1:1⋄⍵×⍺⍺⍵-1}⋄(f fact) 2
21:41
@user VALUE ERROR
ngn
ngn
@user in k
@ngn Nice, does k not disriminate between operators and functions?
'{⍵≤1:1⋄⍵×⍺(⍎⍺)⍵-1}'{⍵≤1:1 ⋄ ⍵×⍺(⍎⍺)⍵-1}
bit of a hack
ngn
ngn
@user it has only adverbs (like apl's mops) but they can't be user-defined
@user functions are first-class (unlike in apl) and can take up to 8 args
I assume not allowing the standard library means I can't make it in dfns.lisp :(
21:44
@rak1507 Could you use this trick? ⋄ {f←∇ ⋄ ⎕CR'f'}⍬
@Adám
┌→────────────────┐
↓ f←{f←∇ ⋄ ⎕CR'f'}│
└─────────────────┘
maybe, but you're still using ∇
I'm not recursing though.
Sure but I think that's still cheating as functions shouldn't be aware of their own existence
⋄ Y←{⎕CR'Y'} ⋄ Y⍬?
21:45
@Adám
┌→──────────┐
↓ Y←{⎕CR'Y'}│
└───────────┘
using the name Y
I'm so lost. I don't see at all how y'all read all these restrictions into the OP.
I mean, your answer is allowed to use recursion itself
Oh yeah :( the haskell one uses the name Y
That's no fun
So a function that uses ∇ or Fix or whatever is fine
21:47
ah ok
Can someone restate in very simple non-technical non-domain-specific language what's asked for?
Assuming someone wants to write something like a factorial without recursion, they should be able to use your function Fix
@MartinJaniczek Doesn't answer my question. Sorry. Try re-reading my question.
But you don't even have to implement that, as it's allowing named recursion @MartinJaniczek
21:49
So the function factorial takes two inputs, f and n. facorial handles the base case where n is less than or equal to 1, otherwise it returns n * f(n - 1), assuming f can handle the recursion.
@user But I can use recursion in my solution?
@Adám write a short function that takes a function b and returns the value c that b will return when given c -- which sounds impossible
Sure, yeah
The Y-combinator (and other fixed-point combinators) just turn that incomplete factorial into a normal function taking a single n
Fix f = f(Fix f) if you're cheating
which is what the haskell one does :(
@Adám I'm unsure where you want to draw the line. Can my problem statement assume you know what functions are?
21:52
@MartinJaniczek Only in the APL sense. Your answer employed technical domain-specific language (a formula in a language I don't know.)
The question allows reading from input. Perhaps if Fix could take f as a string, it might be easier to do?
@user And what inputs may I ask for? Can I take two functions and one variable, one function determines the base case, one the relationship, and a variable for the input?
I think it's just the function, since not all functions look like if something then basecase else ∇ next
"the"‽
Ah, so we assume the function itself when used enough times stabilises?
Pretty much, yeah
This is easier to do in a language with lazy evaluation and higher-order functions
21:54
Sounds like ⍣≡ then. No recursion.
I would've preferred to do y f = let x = f x in x for haskell but oh well :(
No, wait, the function has to be able to specify how it wants itself to be called next time around the loop…
Except the will never be true, and since APL is strict (it is strict, right?), it'll just hang
I don't think ⍣≡ is right anyway.
<moon-child> it's closer to ⍣_ (infinity), but still functionally equivalent
21:56
⋄Fix←{∇(⍎⍺⍺)⍵}⋄'{1≥⍵:1⋄⍵×⍺⍺⍵-1}'Fix 2
But that function cannot be recursive or refer to itself by name, so how can it specify?
@user VALUE ERROR
<moon-child> the idea being that if the function converges, repeated applications have no effect, so it doesn't matter if you stop as soon as you reach the fixed point
@Adám Which function are you talking about? This is getting confusing
There's only one. The one that specifies the relationship.
@Adám The input to Fix?
21:58
Yes.
But Fix is a function too (or they're both operators, if we're talking in APL now)
@user Fix should probably be an operator, unless we're using a string to pass the "function" in.
@Adám The function uses another function given to it
@Adám I think that even with a string, it might need to be an operator
@user What? No, the function specifying the relationship doesn't take a function, does it?
@user Why?
It does, that's how it fakes recursion
22:00
But who feeds it that function? And what function is it fed? Itself?
@Adám So as to pass only the function and not the function's argument at a time
yeah
Fix feeds it to the function
@user Can't parse that English sentence.
Fix takes a function f and passes f(f(...f(f(f(Fix f)))))) to it
22:02
@user I don't understand.
The incomplete factorial from above takes two arguments, a function f2 that knows how to handle n greater than 1, and n
OK.
Fix fills in f2 for it
Wat. Lost me there.
Gimme a minute, there was a nice article about this
Here's one about the Y combinator that might help
So basically Fix makes it so the returned function expands to `n × ((n-1) × ((n-2) × 1))
22:06
Returned function? I'm lost again.
Fix takes an incomplete function and returns a "recursive" function
Factorial = Fix IncompleteFactorial... Factorial is the returned function
It's like an operator, but the weird part is that the Fix's argument, f, is also an operator
Sounds like something APL can't do because functions can't take functions. BQN might be able.
Could operators take operators?
22:09
So IncompleteFactorial's type signature looks like CompleteFunction -> Int, where a CompleteFunction is Int -> Int. And Fix's signature would be IncompleteFunction -> CompleteFunction.
youtu.be/pkCLMl0e_0k?t=10953 there's a derivation of it in python at the timestamp
@MartinJaniczek Not directly, but you might be able to trick them into doing so by binding operands to them temporarily.
See also this.
⋄Fix←{(⎕CR∇)(⍎⍺⍺)⍵}⋄'{1≥⍵:1⋄⍵×(⍎⍺⍺)⍵-1}'Fix 2
@user VALUE ERROR
⋄Fix←{store←∇⋄(⎕CR 'store')(⍎⍺⍺)⍵}⋄'{1≥⍵:1⋄⍵×(⍎⍺⍺)⍵-1}'Fix 2
22:13
@user VALUE ERROR
ngn
ngn
@user story: i challenged john scholes once to write the Y in apl, because of course you can't do that. months later we wrote the lisp interpreter in dfns together, as an exercise for "young" me. when we got the tests right he looked at me like "see? it's possible" (he didn't say it, but i got the idea)
lol cool
⋄ Fix←{store←∇⋄(⎕CR 'store')(⍺⍺)⍵} ⋄ '{1≥⍵:1⋄⍵×(⍎⍺⍺)⍵-1}'Fix 2
@Adám
┌→──────────────────────────────────────────────────────────────┐
│ ┌→───────────────────────────────────┐ ┌→─────────────────┐   │
│ ↓ store←{store←∇ ⋄ (⎕CR'store')(⍺⍺)⍵}│ │{1≥⍵:1⋄⍵×(⍎⍺⍺)⍵-1}│ 2 │
│ └────────────────────────────────────┘ └──────────────────┘   │
└∊──────────────────────────────────────────────────────────────┘
@user The above isn't a valid argument for Hm. OK, so returns a mop.
22:15
@ngn you can write ~~FORTRAN~~ LISP in any language
but not easily
'Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.'
ngn
ngn
@Wezl hehe, right. there's another one about every sufficiently complex piece of software containing a bad impl of lisp :)
@rak1507 ah, you're faster than me again
Aside: Why is {∇∇} not an operator?
ngn
ngn
@Adám it doesn't contain ⍺⍺ or ⍵⍵
@Adám no reference to aa / ww? (sorry for transliteration, I'm on mobile)
22:19
@ngn @MartinJaniczek I know, but why isn't ∇∇ enough to make it an operator?
ngn
ngn
what should it be, a nop? :) (niladic op)
A dfn without is still monadic, so I'd say a mop.
ngn
ngn
apl functions are always ambivalent
apl operators have fixed arity
No, Dyalog dfns are.
@ngn True. Still.
ngn
ngn
@Adám true, point taken
the comparison with a dfn is not appropriate because a dfn is ambivalent no matter if it contains ⍺ or not
22:23
Yeah, that's a good point.
ngn
ngn
i wonder if ∇∇ is a valid double recursion in a dfn (not containing ⍺⍺ or ⍵⍵)
It isn't.
⋄ {∇∇⍣0⊢⍵}42
ngn
ngn
it seems ∇∇ is considered a single token
@Adám SYNTAX ERROR
I bet ∇∇∇ is considered ∇∇ ∇ though. Because stupid tokeniser.
ngn
ngn
22:25
@Adám isn't that correct? i like my tokenizers stupid :)
@ngn Correct?
<moon-child> can you ask dyalog to only perform word formation? (Like monadic ;: in j)
⋄ Fix←{({aa Fix ⍵}(⍎⍺⍺))⍵} ⋄ '{1≥⍵:1⋄⍵×⍺⍺ (⍵-1)}'Fix 4
@user VALUE ERROR
<moon-child> ⋄{∇∇∇}
{∇∇·∇}
ngn
ngn
@Adám well, it greedily matches from the left whatever token it can consume and that's ∇∇. then only one ∇ is left.
22:26
⋄ Fix←{aa←⍺⍺⋄({aa Fix ⍵}(⍎⍺⍺))⍵} ⋄ '{1≥⍵:1⋄⍵×⍺⍺ (⍵-1)}'Fix 4
@user VALUE ERROR
Huh, I just tried in Dyalog, and it worked. Doesn't work on TIO either
@ngn Yes but stupid stuff like that and 2f3 being 2 f3 precludes adding hyperators and additional numeric types.
@user For different reasons, I think. TIO because it runs into a bug we fixed in 18.0, and the bot because is actually a cover function.
<moon-child> not if you expand the character set
ngn
ngn
@Adám just abandon the cult of backw.. ok, enough whinging from me about this :)
22:31
lol
@ngn Might actually be a viable business model. It seems that every time we change something that breaks backwards compatibility in a seemingly insignificant way, we end up having customers paying us extra to either build custom versions of the interpreter without the change, or add a secret I-beam to disable the change.
E.g. we fixed a bug in that caused ⍳⍬ to return ⎕IO instead of the correct ⊂⍬. You'd think nobody in their right mind would ever write ⍳⍬ to get ⎕IO but sure enough…
What if you make changes to ⌶!
:-D
new primitive: ⌶⌶
Another one is when complex number support was added, ⎕VFI started accepting complex numbers. Oh dear.
@rak1507 That's invalid on its own, but there's virtually unlimited design space in .
ngn
ngn
22:36
@Adám this story sounds familiar. are you sure it hadn't been fixed before you came?
@ngn Sure, that's history, but we're still suffering from it.
surely that sort of thing should be a simple find and replace
If your code was stored in text files, sure.
what else would it be stored in... oh no...
@rak1507 Component files!
22:41
Ah, I don't know what they are
ngn
ngn
proprietary blobs like .dws
Can they not easily be edited?
ngn
ngn
yes, with a proprietary editor that isn't very good at find/replace
well if they already have the editor, what's the problem?
oh
Not edited per se, you can tie them, extract components, then replace/add/remove comppnents.
22:42
facepalms Dyalog
@Wezl This isn't a Dyalog thing, but a standard APL thing.
@Adám The Y combinator results in infinite recursion in a strict language like BQN, but you can implement the Z combinator. Here I've used ○⊢ to convert subjects to functions and ⊑⟨…⟩ to convert a function to a subject.
For the Y combinator you'd replace {𝕩{(𝔽𝕗)∘⊢𝕩}} with {𝕏𝕩}.
* faceplams APL in general
@Wezl Think back to a time when text files didn't exist. How would you store data on disk tape?
22:44
See also the tacit Z combinator in I.
Many APL users have systems that were originally written back then, and have simply been ported from system to system since.
Back when the D in DOS wasn't there yet. There was no "disk" or tree structure you could use to organise your stuff.
ngn
ngn
right, i've heard a component file is more like whole filesystem with its own file permissions
Exactly.
The first component is (usually ― standard usage) the "FAT", i.e. ToC.
And it gives precise control over various types of access to each component, stores time stamps and who last changed each component too.
ngn
ngn
completely pointless since a few decades ago
You couldn't tell the OS to get you file "abc". That was simply meaningless.
@ngn Sure, but converting or rewriting a large system is expensive and error-prone.
ngn
ngn
22:50
@Adám that's precisely why i'd rather leave it to my operating system :)
@ngn Leave what?
Companies tend to prefer lots of small magnitude expenses even if they add up to much more over time than a single large expense now.
ngn
ngn
@Adám the responsibility of dealing with file systems
@ngn Sure, but that wasn't an option back then. If were there, you'd have used a component file too.
ngn
ngn
@Adám it's 2021. wake up :)
3 mins ago, by Adám
@ngn Sure, but converting or rewriting a large system is expensive and error-prone.
ngn
ngn
22:53
@Adám are you arguing for the use of component files or against?
@ngn No.
which one
I'm not arguing for or against. I'm only explaining why they are still in use.
ngn
ngn
@Adám would you ever use component files in a new project?
22:56
No.
ngn
ngn
me either
@ngn Would you ever use component files in an old project?
ngn
ngn
@Adám i'd try to get the data out asap
So you'd single-handedly rewrite and QA possibly tens of thousands of functions on your spare time, since management wouldn't want to pay the up-front cost?
(No, I know you'd just quit.)
ngn
ngn
@Adám quite a leap from "get the data out" to that :)
22:59
@ngn Getting the data out isn't enough. You'd have to re-jig all the functions that create/access/manipulate that data too.
ngn
ngn
@Adám when dealing with legacy systems, the first thing you do is extract the data. the old system can keep functioning while you're working on the replacement.
i would feel very uncomfortable working with a file format that tries to steal responsibilities from my file system
23:17
finally think I got the "breakthru" re: bqn erlang interpreter
nice
not working at the moment but i have a functional version of the vm w/ heap and stack effects
tyty
ill be relieved when i get it finally working hah. then the fun part of getting it to work w/ the latest version.
@cannadayr Yes!
getting it to work w/o using mutable variables was... fun.
@cannadayr Yeah, seems like quite an adventure. I'm glad I got to see what's involved, and that I didn't have to do it.
23:21
@Marshall ya dude, the parts are finally feel like theyre coming together
it wasnt that bad when i realized what was happening
i did things like "Program Counter successor = ..." "stack successor = ..."
its inefficient because its calculating the leb128 offsets multiple times
@cannadayr Good news is we scrapped LEB128 a while ago.
yea i think i saw that. ive just been focusing on this bytecode version. once i get it working and compiling code updating it to the newest format will be another adventure
i doubt im going to pursue converting it to a code generator for the time being. id rather use it to write applications.
@cannadayr Shouldn't be too hard, really. The only thing that might be difficult is that you have to provide •Glyph and •Decompose from the system functions to the runtime and formatter.
Which is probably actually much easier in Erlang than JS. Well, •Glyph in the runtime is weird because it can't actually work until the runtime is defined, but it's not currently used and would only be needed for optimization (primitives can't be ordered but their glyphs can be). I might remove it or try a different strategy.
@Marshall ill keep an eye out. i gave up guessing what to optimize. im just using lists for everything at the moment.
i figure if/when its working ill have a better idea of where the implementation bottle necks are
the only types i currently have are values, operators, and environments
@cannadayr I doubt the array storage will be an issue for a while. It's pretty much all function calls until I improve the compiler.
23:34
the heap is a general binary tree module from stdlib
i think using bqn to write distributed applications might be pretty neat ngl. thinking about basics to write.
like a DHT or CRDT
04:00 - 21:0021:00 - 00:00

« first day (1441 days earlier)      last day (1510 days later) »