upghost 42 minutes ago

Well if we are showing off sudoku solvers, it would be a sin not to share this one:

  sudoku(Rows) :-
        length(Rows, 9),
        maplist(same_length(Rows), Rows),
        append(Rows, Vs), Vs ins 1..9,
        maplist(all_distinct, Rows),
        transpose(Rows, Columns),
        maplist(all_distinct, Columns),
        Rows = [As,Bs,Cs,Ds,Es,Fs,Gs,Hs,Is],
        blocks(As, Bs, Cs),
        blocks(Ds, Es, Fs),
        blocks(Gs, Hs, Is).

  blocks([], [], []).
  blocks([N1,N2,N3|Ns1], [N4,N5,N6|Ns2], [N7,N8,N9|Ns3]) :-
          all_distinct([N1,N2,N3,N4,N5,N6,N7,N8,N9]),
        blocks(Ns1, Ns2, Ns3).
While not one line, to me it is pareto optimal for readable, elegant, and incredibly powerful thanks to the first class constraint solvers that ship with Scryer Prolog.

If you want to learn more about it or see more of Markus's work:

https://www.metalevel.at/sudoku/ https://youtu.be/5KUdEZTu06o

More about Scryer Prolog (a modern , performant, ISO-compliant prolog written mostly in rust) https://www.scryer.pl/ https://github.com/mthom/scryer-prolog

eigenvalue an hour ago

It's cool in a novelty way that it’s so short, but I would infinitely prefer something like this for actual work and understanding:

  def solve(grid):
      def find_empty(grid):
          for r in range(9):
              for c in range(9):
                  if grid[r][c] == 0:
                      return r, c
          return None

      def is_valid(grid, num, pos):
          r, c = pos
          if num in grid[r]:
              return False
          if num in [grid[i][c] for i in range(9)]:
              return False
          box_r, box_c = r // 3 * 3, c // 3 * 3
          for i in range(box_r, box_r + 3):
              for j in range(box_c, box_c + 3):
                  if grid[i][j] == num:
                      return False
          return True

      def backtrack(grid):
          empty = find_empty(grid)
          if not empty:
              return True
          r, c = empty
          for num in range(1, 10):
              if is_valid(grid, num, (r, c)):
                  grid[r][c] = num
                  if backtrack(grid):
                      return True
                  grid[r][c] = 0
          return False

      backtrack(grid)
      return grid
cduzz 13 hours ago

I'll sometimes gauge code complexity by comparing the number of lines of code against the output of

  tar -cf - . | gzip | base64 | wc -l
IE "how much does it compress?"

Looking at APL -- I'm reminded of what happens if I accidentally send the gzipped output to my tty...

I'm impressed that there's anyone who can follow along (can you find the bug?) to code like

p←{(↑⍵)∘{(⍺∨.=⍵)/⍳n×n∘}¨,⍵},(n*÷2){⍵,⍺⊥⌊⍵÷⍺}'⍳n n←⍴⍵

It really feels like compressed binary data where everyone's got a copy of the dictionary already...

  • bryancoxwell 13 hours ago

    Legitimately curious how APL programmers think about maintainability and readability. Is code just thoroughly commented or otherwise documented?

    • mlochbaum 3 hours ago

      The most uncompromisingly APL-ish code I've written is the BQN compiler[0]. Hard to write, hard to extend, hard to refactor. I generally recommend against writing this way in [1]. But... it's noticeably easy to debug. There's no control flow, I mean, with very few exceptions every line is just run once, in order. So when the output is wrong I skim the comments and/or work backwards through the code to find which variable was computed wrong, print stuff (possibly comparing to similar input without the bug) to see how it differs from expectations, and at that point can easily see how it got that way.

      The compiler's whole state is a bunch of integer vectors, and •Show [a,b,c] prints some equal-length vectors as rows of a table, so I usually use that. The relevant code is usually a few consecutive lines, and the code is composed of very basic operations like boolean logic, reordering arrays with selection, prefix sum, and so on, so they're not hard to read if you're used to them. There are a few tricks, which almost all are repeated patterns (e.g. PN, "partitioned-none" is common enough to be defined as a function). And fortunately, the line prefaced with "Permutation to reverse each expression: more complicated than it looks" has never needed to be debugged.

      Basically, when you commit to writing in an array style (you don't have to! It might be impossible!) you're taking an extreme stance in favor of visible and manipulable data. It's more work up front to design the layout of this data and figure out how to process it in the way you want, but easier to see what's happening as a result. People (who don't know APL, mostly) say "write only" but I haven't experienced it.

      [0] https://github.com/mlochbaum/BQN/blob/master/src/c.bqn

      [1] https://mlochbaum.github.io/BQN/implementation/codfns.html#i...

      • upghost 19 minutes ago

        God bless, my hat goes off to you sir. I have trouble wrapping my head around the concept of first class functions in ndarrays, let alone implementing it in hardcore APL. That has to be a feat on par with Hsu's Co-Dfns.

        Don't suppose you can point to any resources to help wrap your head around BQN, do you?

    • dzaima 3 hours ago

      Once you've learned the syntax of the language, long expressions like that are about as readable as however-many-dozen lines of JS/Python with 1-to-3-character variable names; i.e. some parts may be obvious if they're a common pattern or simple enough, but the big picture may take a while to dig out.

      Probably the biggest readability concern of overly-golfed expressions really is just being dynamically typed, a problem shared with all dynamically-typed languages. But array languages have the problem worse, as nearly all operations are polymorphic over array vs number inputs, whereas in e.g. JS you can use 'a+b' as a hint that 'a' and 'b' are numbers, & similar.

      If you want readable/maintainable code, adding comments and splitting things into many smaller lines is just as acceptable as in other languages.

    • t-3 10 hours ago

      You don't really have to worry about keeping track of tons of functions, variables, structs, classes, etc., and trying to keep all the names straight in your head - all you need is to know the symbols, so it's in some ways easier than reading a complex function in more verbose languages where you might need to lookup stuff from several libraries just to understand what's going on. Also, that one line is ~100 characters, each of which probably covers ~0.5-1 lines in other languages, so you should expect to set aside a similar amount of time to reading and understanding it.

    • shawn_w 11 hours ago

      I suspect that if you're fluent in the language, understanding an expression written in it comes just as easily and quickly as reading a sentence in a book does to me.

      • andylynch 7 hours ago

        That’s exactly what they say. Though most kdb I’ve see in business looks more like Python.

    • rtpg 9 hours ago

      my impression is that the language is used more for scripts than for "code" in a true sense. A bit of "how much can you juggle in your mind" going on

    • genewitch 11 hours ago

      i've only seen these style of languages commented after a contest is over on stack programming challenges. I have no idea how one would learn all this stuff from code in the wild (like i learned most of python, for example). then again, i don't go searching github for k, apl, or perl for that matter.

      I'm sure each of those languages makes some guarantee about the sorts of errors that can be introduced - as opposed to C (let me pick on it) where the errors you know you can introduce, and the errors that are introduced aren't a large union. However i have a hard enough time typing english consistently, so the various "symbol-y" languages just glaze my eyes, unfortunately.

      It almost "feels" like these languages are an overreaction to the chestnut "they must get paid by LoC".

  • rak1507 13 hours ago

    I'm not sure why it would be any more impressive or surprising than the billions of people who read and write in non English alphabets

    • cduzz 13 hours ago

      That's a really good point...

      But -- (and forgive me if I'm totally wrong) -- this isn't just "non-english" but "non-phonetic" which is a smaller set of written languages, and the underlying language is ... math.... so understanding the underlying grammer itself relies on having decades of math education to really make it jive.

      If this code is just a final result of "learn math for 2-3 decades, and spend years learning this specific programming language" -- my statement stands. Interacting with this kinda binary blob as a programming language is impressive. I think I read somewhere that seymour cray's wife knew he was working too hard when he started balancing the checkbook in hex...

      • rak1507 13 hours ago

        The underlying language isn't really very mathematical, at most there's a bit of linear algebra in the primitives but that's it. You certainly don't need any sort of formal maths education to learn APL. There are about 50 or so new symbols, which is not a big ask, with any sort of focus the majority of the syntax etc can be learned very quickly. The "bugs" in your original code stand out very clearly because things like "∘}" don't make sense, ∘ being "dyadic" (infix).

        • RodgerTheGreat 12 hours ago

          and it bears mention that a decent chunk of those symbols are things nearly everyone is familiar with from other languages (+, -, =, etc), symbols you've probably seen in math class or on your graphing calculators (÷, ×, ≠, ⌈, ←, etc), and symbols with very strong mnemonic associations once you've seen them explained (≢, ⍋, ⍳, ⌽, etc).

nebulous1 15 hours ago

Here is the line, it is written in K. K is a language created by the same person (Arthur Whitney) based on APL and Scheme.

  x(,/{@[x;y;]'(!10)^x*|/p[;y]=p,:,3/:-3!p:!9 9}')/&~*x
  • pjot 14 hours ago

      > Advocates of the language emphasize its speed, facility in handling arrays, and expressive syntax.
    
    Indeed.

    https://en.m.wikipedia.org/wiki/K_(programming_language)

    • brookst 14 hours ago

      “Expressive” = like two cats fought while standing on the keyboard

      • rtpg 9 hours ago

        I've been messing with Uiua (https://www.uiua.org/) a good amount recently, and find its sort of dance between having a stack and being an array language somehow gets you to a nice level of legibility despite being a combo of two styles that tend to generate line noise.

        • PhilipRoman 22 minutes ago

          Cool language. I happened to notice the ⍜ operator, which operates on a transformed array, then reverts the transformation. Not sure if other array languages include this, but it's a really cool idea. I always found the traditional map/filter operators to be limiting in this regard, kind of like trying to write expressions without using parentheses.

        • dahart an hour ago

          The front page there has examples like “÷3/+∿⊞×⊟×1.5.220×τ÷⟜⇡&asr” - is that closer to noise, or does it actually look more readable than K once you get used to both? I’m kind-of intrigued by the built-in multimedia output, but still this language looks scary and impractical at first glance. How does it compare to using numpy & jupyter? Do a lot of people prefer the extreme tenseness over using typeable keywords? I’m curious why it lets you type the readable operators but wants to turn them into glyphs; wouldn’t it be more approachable, more readable, and make more maintainable code, if it just used the keywords instead of glyphs?

        • g8oz 2 hours ago

          Thanks for the link, it looks like a fascinating language

      • xwolfi 13 hours ago

        I work with it daily in a bank, and I couldnt find a better way to express it. Many colleagues throwing their keyboard in despair at this stupid impossible to remember syntax.

        • nine_k 9 hours ago

          Not that it's impossible to remember, bit it's definitely contrary to most traditional use of the symbols employed in it, though not without logic. My favorite is the functions from io package, called 0, 1, and 2 (yes, numbers) which handle interaction with stdin, stdout, and stderr respectively. In dyadic form they at least have a colon, but in monadic form they look like plain numbers: 1 "Hello world".

          I suspect that to study k (and use kdb) efficiently, you need to actively forget what you knew about the syntax of other languages, and study k as a language from Mars that happens to map to ASCII characters somehow.

        • rak1507 13 hours ago

          There are a lot of things in various programming languages which are hard to remember, but k and array languages have such a small surface area, not being able to remember it while working with it daily amounts to learned helplessness.

          (source: mostly amateur k programmer, also worked with it in a bank, find it vastly easier to read/write/remember than most mainstream languages)

        • anonzzzies 9 hours ago

          It is really easy to remember; it is so small that remembering is the least of the issue. The rest is just using it a lot; I find it readable and nice to work with. Unlike other some other languages we get shoved down your throats.

        • aguaviva 12 hours ago

          Which is why banks love it. Because one has to be pretty smart to be able to wade through all that nutty, impossible to remember syntax.

          Therefore, k is a smart choice, and people who use k in business applications must be really smart.

          • inopinatus 12 hours ago

            "Debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?"

            — Kernighan, Brian. The Elements of Programming Style (2e). McGraw-Hill, 1978.

            • userbinator 11 hours ago
              • nine_k 9 hours ago

                It's a nice interpretation.

                I prefer a different approach: "smart is good; clever isn't smart". If you have to express something in a clever, that is, highly contrived but actually working way, it means that you lack the right way to express it, and maybe your mental model of the problem is not that good. The theory of epicycles is clever; Kepler's laws are smart.

              • darkwater 6 hours ago

                This can probably true for some people, but still will not work for many other. One probable outcome of a frustrated debugging session is "let's rewrite/refactor it to make it easier to debug next time", and not self-enlightenment.

              • IshKebab 10 hours ago

                Very unconvincing. If you become cleverer you can just write even more clever code and still not be able to debug it.

            • chii 10 hours ago

              > how will you ever debug it?

              By being so smart that your program has obviously zero bugs in it!

              • nosianu 9 hours ago

                This view is too static.

                That is not possible, because the environment can (and at some point always will) change which wasn't planned for due to a lack of working crystal balls. Data, user behavior, the network, the system(s) the software runs on can all change over time.

                Also, it is way too expensive to try to cover every single conceivable possibility, so we deliberately leave holes.

                For non-trivial things we often prefer to wait to see what problems actually come up during use, and then fix exactly those, but not the many more problems that could come up but are too unlikely and/or too costly to guard against.

                In a living environment the software lives too, and keeps changing and adapting.

                • boomlinde 8 hours ago

                  > That is not possible, because the environment can (and at some point always will) change which wasn't planned for due to a lack of working crystal balls. Data, user behavior, the network, the system(s) the software runs on can all change over time.

                  It sounds to me like you are describing a change of problem, not bugs in the solution. If in the future someone redefines the concept of a Sudoku puzzle such that this solution is no longer applicable, or tries to use the solution verbatim in a language which is different from K and therefore yields different results, it's not a bug in the original code that it's not a solution to that new problem. It's still a solution to the same problem it was always a solution to.

                  I can see what you mean in a practical sense, but also consider (practically) that a lot of problems can be broken down into smaller, well-defined problems which are themselves practically immutable. You can throw the solutions to such problems out when you no longer need them, and come up with solutions to whatever new problems replaced the original problems.

                • chii 9 hours ago

                  you might've missed the quip, since this whole thread is about a quote, which i'm countering with an alternative quote from Hoare

                  > There are two methods in software design. One is to make the program so simple, there are obviously no errors. The other is to make it so complicated, there are no obvious errors.

                • dotancohen 5 hours ago

                  I believe that you are addressing maintainability, not debugging.

          • ryanjshaw 10 hours ago

            The average bank/company would rather have an average solution maintained by 10 easily replaceable average developers than a nutty, smart solution only understood by 1 highly talented developer.

            • aguaviva an hour ago

              Which was precisely my point (and I agree with all the responses in this thread), though my wording and light sarcasm seems to have been a bit too dry, and didn't quite take up as intended.

            • Moru 8 hours ago

              You could also say that the average bank/company should have learned from previous mistakes doing exactly that for many decades. Select a language that is well tested, understood and supported. Set a limit on cleverness and instead focus on maintainability and simplicity.

              • speed_spread 5 hours ago

                If only. In my experience, banks end up building a solution that is maintained by 100 mediocre developers that a reasonably smart developer can't make sense of when it behaves erratically or has extremely poor performance.

                • ryanjshaw 4 hours ago

                  I described the theory. You have described the practice :)

            • queuebert an hour ago

              Keeping skill barriers low keeps wages low as well.

    • hilux 10 hours ago

      But possibly not its maintainability.

  • nine_k 9 hours ago

    Lines of code is a poor metric, because languages use lines differently.

    A much better measure would be the number of nodes in a parse tree, of semantically meaningful non-terminals like "a constant" or "a function call".

    An even better measure would also involve the depth and the branching factor of that tree.

    • xelxebar 7 hours ago

      Just... no. What are you even trying to compare? UX of a language matters. Clarity, thinking paradigm, expressability etc. all matter and are affected by the visual size of code.

      A one line solution takes up very little visual real estate. That matters a lot when you are working on some more complex problem. Flitting your eyeballs around a screen takes orders of magnitude less effort than scrolling around and navigating files. Cognitive load is important.

      We really need to burn this vague "only semantics matter" scourge that's creeped into our programmer values these days. I'm sorry, but I care about things like incentives against over-engineering, ease of directly thinking in the problem domain, and simplicity of the encompassing ecosystem.

      A terse one-line solution tells me there is virtually no room for over-engineering. Even without knowing K, I can see obvious constants side-by-side, telling me it's likely using a direct data representation of the problem in its code. Does K culture encourage code like that? Does programming in K bias you towards directness and simplicity? Then please, I want some of that special sauce on my team.

      </rant>

      • dahart 21 minutes ago

        Don’t get confused between using smaller keywords and actually understanding the problem at hand. Terse languages do absolutely nothing to prevent over-engineering. They might even contribute by giving a false sense of simplicity and a tendency to prevent certain kinds of code reuse. To prevent over-engineering on large projects, you don’t need a terse language at all, you need the right mentality, the right management & product team, good team culture & cohesion, strong code review process, and job performance metrics that align with not over-producing code.

        It seems like parent’s metric (size of parse tree) would easily optimize for terseness and penalize bloat, regardless of language, so maybe your reaction was too reflexive. UX of a language does matter a bit, and one that’s too terse incurs development friction and technical debt when used in larger projects. Just study the history of Perl and why it’s not widely used.

        What a one liner looks like is more or less the worst possible metric to use for large software projects. In any language, the style of code changes the larger the codebase, and cleverness and terseness become a liability. https://www.teamten.com/lawrence/writings/norris-numbers.htm...

      • lukan 6 hours ago

        "A one line solution takes up very little visual real estate. That matters a lot when you are working on some more complex problem."

        When I work on some more complex problem, I like to think about the problem, not spend energy decoding condensed text. Scrolling a bit more verbose, but clear code, is faster for me.

        • cenamus 5 hours ago

          I think the difference is not a bit of scrolling, but rather the whole program on half a page vs 10 files à 200 lines of mostly noise

          • lukan 5 hours ago

            There is noise and there is self explaining code. One liners for complex problems are a nice challenge, but are seldom clear to read.

      • agumonkey an hour ago

        I mentally work like what parent described. I plug ast node in my mind when I read. I like operating with combinators, graphs/trees of them that I almost naturally understand the results of.

        Any language that add complexity at that layer loses me, and APL, even with crude visuals is not far from that.

      • Etherlord87 6 hours ago

        Why not create a programming language, that uses all possible unicode codepoints to further decrease the number of characters used? That would be so much more readable!

    • smokel 8 hours ago

      The built-in functions and API to a system library spoil these metrics. As an example, consider HQ9+, which is pretty good at printing "Hello, world!" for instance.

      https://cliffle.com/esoterica/hq9plus/

    • skrebbel 3 hours ago

      This oneliner was obviously done for the giggles, and nobody pretends it's reasonably readable code. Getting anal about definitions here is entirely missing the point. (which is "look, K lets you write extremely dense code!")

      • wk_end 3 hours ago

        I don’t know if that’s the case, simply because all code that I see written by array language programmers looks like code golf. Even the language implementation itself!

        https://code.jsoftware.com/wiki/Essays/Incunabulum

        • mlochbaum 2 hours ago

          Is this because all the code you see is through HN or similar? No one's going to share something titled "an unremarkable script I use to help run my business" here. Not sure what your threshold for code golf is, but you can see APL written in a variety of styles by searching Github. It doesn't recognize K but does have Q, which is basically K plus keywords, obviously promoting more verbose code. Whitney originated the dense style of implementation shown at your link, and a few other implementers (including myself in the past) have picked it up, but it's not that common. For example April, GNU APL, Kap, Goal, and Uiua all use an idiomatic style for their implementation languages.

          APL: https://github.com/search?type=code&q=language%3AAPL

          Q: https://github.com/search?type=code&q=language%3Aq

          Implementation: https://aplwiki.com/wiki/List_of_open-source_array_languages

  • sorokod 9 hours ago

    The LoC count and similar metrics have the advantage of an easy calculation.

    Ultimately though,they are a proxy to a more relevant but difficult to determine attributes such as

    Given a reasonably proficient engineer, the amount of time it would take them to resolve a bug in code written by someone else or alternatively extend its functionality in some way.

  • Isamu 14 hours ago

    Not knowing K, am I correct in assuming this is a backtracking brute force solver?

    • o11c 14 hours ago

      From the linked page (and the one linked beyond that), it's a breadth-first search actually. Keep a list of possible puzzle states at all times, pick a blank cell (theoretically arbitrary, but in practice intelligently for performance), add copies of the state with each possibility for that state added.

      • BobbyTables2 13 hours ago

        That sounds like 100+ lines in python or similar languages…

        • throwup238 11 hours ago

          You should be able to do it in under 20 lines using the same matrix operations as the K code via numpy.

          • anonzzzies 9 hours ago

            Numpy is indeed very apl. Just more horrible to me; not python-y and annoyingly verbose for the apl-er.

        • hrzn 7 hours ago

          A few years back I made a modest attempt at writing a concise yet readable sudoku solver in Python - in about 29 lines: https://github.com/hrzn/sudoku/blob/master/sudoku.py

          Could have been made shorter at the price of readability.

          • forgotpwd16 4 hours ago

            Looks nice. Since imports numpy can utilize (more of) numpy's operations to squeeze validation functions and nested fors to one. Should result in shorter code but readability will probably depend on reader's experience in array programming.

        • otteromkram 12 hours ago

          It probably isn't. At least, not for Python.

  • lofaszvanitt 11 hours ago

    It has strong perl vibes and it brings back ptsd :D. Maybe this overshortification of things is a personnel or intelligence indicator of some sorts.

  • TZubiri 5 hours ago

    I thought it was written by Ursula K. Le guin.

    Not sure where I got that from.

  • make3 13 hours ago

    "one line in your custom language" is not one line at all lol

    • Spivak 12 hours ago

      To be fair K is a real language that's used by more than just him.

      Why array languages seem to gravitate to symbol soup that makes regex blush I'll never know.

      • IshKebab 10 hours ago

        Yeah I think MATLAB and Mathematica are waaay more used than K et al. They just don't look insane so people aren't posting them on HN as much.

      • fodkodrasz 10 hours ago

        [flagged]

        • exitheone 9 hours ago

          Array language have been around far longer than any "HN crowd".

          • fodkodrasz an hour ago

            Which is totally orthogonal to the original statement, and my reflection to it, which was on one hand statig that seemingly array languages tend to be letter soupy, for which I replied that a selection bias is at play, as array languges are used widely, most notably Matlab is used widely which is not a letter soup. It is simply not regurgulated on the site as it does not seem so hardcore.

            Nevertheless you are right, array langueges have been around earlier, for example Matlab itself dates back to the 1970s.

            I do not understand the awe some are giving them in the comments, they are an easy to understand paradigm, which is very well suited for certain types of problems. Some having overly terse syntax is a thing, but I do not feel that only geniuses can comprehend array programming, anyone who did learn some university level physics or signal processing has the tools in their belt.

  • asah 12 hours ago

    What baud is that? /s

    • speed_spread 5 hours ago

      My cat puked in the modem receiver cup, sorry.

    • genewitch 12 hours ago

      mismatched, whatever it is, that's for sure. It's not quite line noise, so maybe it's just the wrong stop bit?

gorgoiler 11 hours ago

Every K program ought to end in QED, and then I remember that KQED is also a thing, and I wonder if their two worlds have ever overlapped.

(KQED is the Bay Area PBS partner. PBS is the US public television org.)

shahbazac 14 hours ago

I’ve often wondered about languages like APL/k, are the programmers actually able to think about problems more efficiently?

  • Jorge1o1 14 hours ago

    As a kdb+/Q programmer I would say it depends on the type of problem.

    For example, when working with arrays of data it certainly is easier to think and write “avg a+b” to add two arrays together and then take the average.

    In a non-array programming language you would probably first need to do some bounds checking, then a big for loop, a temporary variable to hold the sum and the count as you loop over the two arrays, etc.

    Probably the difference between like 6ish lines of code in some language like C versus the 6 characters above in Q.

    But every language has features that help you reason about certain types of problems better. Functional languages with algebraic data types and pattern matching (think OCaml or F#) are nicer than switch statements or big if-else-if statements. Languages with built-in syntactic sugar like async/await are better at dealing with concurrency, etc.

    • lll-o-lll 14 hours ago

      Which is why C# is the giant ever increasing bag of tricks that it is (unkind people might say bloat…) ;-) Personally, I’m all for this; let me express the problem in whatever way is most natural.

      There are limits, of course, and it’s not without downsides. Still, if I have to code in something all day, I’d like that “something” be as expressive as possible.

    • sudosysgen 13 hours ago

      Well no, not in a non-array programming language. In any language that has a semi-decent type/object system and some kind of functional programming support, `avg a+b` would just be `avg(a, b)`, which is not any easier or harder, with an array type defined somewhere. Once you make your basic array operations (Which they have to be made in q anyways, just in the stdlib), you can compose them just like you would in q, and get the same results. All of the bounds checking and for-loops is unnecessary, all you really need are a few HKTs that do fancy maps and reduces, which the most popular languages already have.

      A very real example of this is Julia. Julia is not really an array-oriented programming language, it's a general language with a strong type system and decent functional programming facilities, with some syntactic sugar that makes it look like it's a bit array oriented. You could write any Q/k program in Julia with the same complexity and it would not be any more complex. For a decently complex program Julia will be faster, and in every case it will be easier to modify and read and not any harder to write.

      • otteromkram 12 hours ago

        Why would it be avg(a, b)?

        What if I want to take the average difference of two arrays?

      • rak1507 13 hours ago

        I don't know what you mean by the q array operations being defined in the standard library. Yes there are things defined in .q, but they're normally thin wrappers over k which has array operations built in.

        • sudosysgen an hour ago

          I don't consider an interpreted language having operations "built-in" be significantly different from a compiled language having basic array operations in the stdlib or calling a compiled language.

  • jksflkjl3jk3 11 hours ago

    For some classes of problems that are easily vectorized, using an array-focused language can certainly make thinking about them and their solutions more efficient, since you can abstract over the data structure and iteration details.

    As a quant, I used kdb+/q quite a bit for 5+ years for mid-frequency strategies, but as I moved towards higher frequency trading that required calculations on the order book that couldn't be easily or efficiently vectorized, then continuing to use array-focused languages would have only complicated reasoning about those problems.

  • omoikane 11 hours ago

    I went to this tech talk on Dyalog (a modern APL-like language), and the speaker makes the argument that the notation allows certain idioms to be recognized more easily:

    https://youtu.be/PlM9BXfu7UY?si=ORtwI1qmfmzhJGZX&t=3598

    This particular snippet was in the context of compilers, but the rest of the talk has more on Dyalog and APL as a system of mathematical notation. The underlying theme is that optimizing mathematical expressions may be easier than optimizing general code.

  • lokedhs 4 hours ago

    "More efficiently"? Maybe. It opens up a new way to think about solutions to problems. Sometimes those solutions are more efficient, and sometimes they are just different.

    It's a useful thing to learn though. And dare I say it, fun. Even if there was zero benefit to it, it'd still be fun. As it turns out, there really are benefits.

    For me, the biggest benefit is when I'm working with data interactively. The syntax allows me to do a lot of complex operations on sets of data with only a few characters, which makes you feel like you have a superpower (especially when comparing to someone using Excel to try to do the same thing).

  • michaelg7x 3 hours ago

    I've found that the challenge is to "think in vector operations" rather than of iterating over the same data. The tricky part is figuring out how to get an operator to do the right thing over an array of stuff on the left hand side and this list/bag/etc of arguments on the right

  • 082349872349872 10 hours ago

    one nice thing about the array language style is that it's possible to talk about variations on algorithms where the relevant code snippets, being a few characters, fits inline into the discussion; more traditional vertically-oriented languages that take handfuls or dozens of lines to say the same things need to intersperse code display blocks with expository prose

  • giraffe_lady 14 hours ago

    Hillel Wayne writes about it on his newsletter every once in a while. He's convinced me that he does in fact think through some problems better in array languages but I still can't really conceive of what that experience is like.

    • RodgerTheGreat 12 hours ago

      there are several open-source K environments available, some which even run in the browser:

      http://johnearnest.github.io/ok/index.html

      if it's something you're interested in trying i'd be happy to point you toward more resources, and i'm sure there are plenty of other arraylang tinkerers reading this thread who could help, too

upghost 11 hours ago

Most people are put off by the symbols, that wasn't really the issue I had.

So I do love APL and arraylangs, and learning them was really helpful in a lot of other languages.

But they never became a daily driver for me not because of the symbols, which were honestly fine if you stick with it long enough, but after about 3-4 years of dabbling on and off I hit a wall with APL I just couldn't get past.

Most other languages I know there is a "generic-ish" approach to solving most problems, even if you have to cludge your way through suboptimally until you find "the trick" for that particular problem and then you can write something really elegant and efficient.

APL it felt like there was no cludge option -- you either knew the trick or you didn't. There was no "graceful degredation" strategy I could identify.

Now, is this actually the case? I can't tell if this is a case of "yeah, thats how it is, but if you learn enough tricks you develop an emergent problem solving intuition", or if its like, "no its tricks all the way down", or if its more like, "wait you didn't read the thing on THE strategy??".

Orrr maybe I just don't have the neurons for it, not sure. Not ruling it out.

  • lokedhs 4 hours ago

    You're not wrong. It's very easy to get that impression when trying to learn the array languages. It's very easy for someone who's used these languages for a long time to look at a problem, and say "why did you use that really elaborate solution, when you can just use ⍸⍣¯1?". No one probably ever told you that ⍸ has an inverse, and how you could use it.

    Even today, after having worked in these languages for years, I am still put off a bit by the walls of code that some array programmers produce. I fully understand the reasoning why it's written like that, but I just prefer a few spaces in my code.

    I've been working on an array language based on APL, and one of my original goals was to make "imperative style" programming more of a first-class citizen and not punish the beginner from using things like if-statements. It remains to be seen how well I succeeded, but even I tend to use a more expressive style when terseness doesn't matter.

    Here's an example of code I've written which is the part of the implementation that is responsible for taking any value (such as nested arrays) and format them nicely as text using box drawing characters. I want to say that this style is a middle ground between the hardcore pure APL style found in some projects and the style you'll see in most imperative languages: https://codeberg.org/loke/array/src/branch/master/array/stan...

    • upghost 3 hours ago

      Very nice! I like the readability-- not sure if thats just indicative of your style or the language, and the map construct is also nice. I don't remember any off-the-shelf map construct, at least not in Dyalog.

      • lokedhs 3 hours ago

        It's likely a combination of both. It's certainly possible to write Kap in a much more condensed form. But things like if-statements and hash maps does allow for a more imperative style.

bazoom42 7 hours ago

The discussions around “line noise”-languages are always intersting.

Most programmers would agree the ‘/’ symbol is at least as clear as writing ‘divideBy’. The question is how often the symbols are used and if their frequency in code justifies learning them.

brador 5 hours ago

Someone should collate exceptional human coding achievements to test future AI.

AFAICT AI cannot replicate this, yet, will be interesting when that day comes.

lucw 11 hours ago

Does anyone have any thoughts on what motivates people to play sudoku or write solvers for sudoku ? I have trouble finding motivation to solve artificial problems. That said I sink hundreds of hours into factorio.

  • bramhaag 11 hours ago

    For me personally, I have little motivation to do classical sudokus. They either have a not-so-elegant solve path (usually set by a computer) or are too difficult for me to solve.

    Variant sudokus on the other hand are a lot of fun. They often have very elegant solve paths and there are many neat tricks you can discover and reason about.

    Some fun ones, if you'd like to try:

    - https://logic-masters.de/Raetselportal/Raetsel/zeigen.php?id...

    - https://logic-masters.de/Raetselportal/Raetsel/zeigen.php?id...

    - https://logic-masters.de/Raetselportal/Raetsel/zeigen.php?id...

    • sltkr 6 hours ago

      To each their own, but the puzzles you linked seem really convoluted compared to regular Sudoku.

      The last puzzle has no fewer than 9 custom rules, in addition to the regular Sudoku rules, and then it also says “every clue is wrogn [sic]” implying there is some meta out-of-the-box thinking required to even understand what the rules are. That is more a riddle than a logic puzzle.

      By contrast, the charm of classical Sudoku is that the rules are extremely simple and straightforward (fill the grid using digits 1 through 9, so that each digit occurs exactly once in each row, column, and 3x3 box) and any difficulty solving comes from the configuration of the grid.

    • akleemans 10 hours ago

      I also mostly enjoy Sudoku variants, most of which I discovered via Geocaches, interestingly. After solving a few I then implemented a solver with customizable constraints, if anyone's interested, should still be available here:

      https://www.sudoku-solver.ch/

  • thom 9 hours ago

    Like many puzzles, there’s a regular release of endorphins as you progress, and a lot of satisfaction in completing something. I enjoy puzzles just like reading a book or playing a game, it’s another world I can step into for a bit of an escape, but I like to think it’s decent mental exercise. Overall I vastly prefer cryptic crosswords where solving each clue genuinely brings a smile to my face, but that’s more of a commitment of time (and for me sometimes a guarantee of frustration). I also like doing puzzles in the newspaper because me and my kids can sit together and all contribute. Coffee, breakfast, sat in the sun with a newspaper and a good pencil[1], absolute bliss if you ask me.

    As for solvers, it’s a very elegant, well-formed problem with a lot of different potential solutions, many of which involve useful general techniques. I used to dabble clumsily in chess engines and honestly it’s the only time I’ve ever ended up reading Knuth directly for various bit twiddling hacks, so it’s always educational.

    1: https://musgravepencil.com/products/600-news-wood-cased-roun...

  • riffraff 11 hours ago

    I don't particularly enjoy sudoku but I like word puzzle games.

    They're all artificial problems, but your brain likes a challenge and you get a dopamine hit when you solve it, I suppose.

  • teo_zero 9 hours ago

    All games are artificial problems, so your question actually is, what motivates people to engage in pastimes?

    Sudoku, crosswords, Simon Tatham's puzzles etc. are an excellent way to pass the time while keep training the mind. Sports are their equivalent for the body.

    Finally, writing solvers for a problem, be it real or artificial, for many is just another variety of puzzle to engage in.

  • proteal 8 hours ago

    idk man, you ask a good question. I think the idea has to do with the saddle you put on the invisible horse that is the game’s problem. Factorio has several complex saddles you must master to tame the beast. In factorio, you can get progressively better at using these saddles to tame even the most unwieldy scenario. Sudoku, at its heart, is not much different than factorio. However sudoku has one narrow problem with many different, increasingly nuanced ways of solving it. Factorio has many different “sudoku” style problems, but each problem needs to be handled differently, with each problem having increasing levels of sophistication. I think you might like factorio more because it’s just a bigger steak to chew on, and you’ve got the right appetite.

  • dclowd9901 9 hours ago

    I don’t care much for sudoku but I do enjoy crosswords quite a lot, which feels like a somewhat arbitrary exercise. I enjoy the fact that I know a lot of words and it makes me feel clever. There’s probably something to that with most puzzle type challenges.

  • ryanjshaw 10 hours ago

    I wasted too much time in my youth trying to min-max, and now I get bored as soon as I figure out, roughly, what the rules and mechanics look like for any game.

  • lgeorget 8 hours ago

    I teach C++ and I made my students code a Sudoku solver last year. It's a very convenient project to give them: self-contained, already familiar, no OS-specific weirdness, you get to use STL data structures, algorithms, very gentle I/Os...

  • jessekv 10 hours ago

    Normally I would concur, but I recently fell into a klondike solitaire binge and the only way out was to write a solver.

  • grujicd 8 hours ago

    I play sudoku almost exclusively on the plane. It's a good way to lose 5-15min.

yumraj 11 hours ago

[flagged]

  • Etheryte 9 hours ago

    Please don't litter HN with LLM spam, it adds nothing of value to the discussion. You even said it yourself, you have no idea if any of the word vomit is true or not.

    • shawabawa3 9 hours ago

      It's your comment that's adding nothing

      It's very interesting that Claude can at least figure out it's a sudoku solver in K where chatgpt fails

  • yumraj 11 hours ago

    Gemini also identifies it as J and this is the output for comparison:

    The programming language used in the code is *J* (pronounced "Jay"). It's a concise, array-oriented programming language known for its expressive syntax and powerful capabilities.

    Here's a breakdown of the code:

    *1. Verb Definition:* * `x(,/{@[x;y;]'(!10)^x|/p[;y]=p,:,3/:-3!p:!9 9}')/&~x` defines a verb (a function in J terminology) and assigns it to the variable `x`.

    *2. Verb Structure:* * `x( ... )/&~x` is the basic structure of the verb. `x( ... )` applies the verb defined within the parentheses to its argument, which will be `x` itself. * `/&~x` is a hook, a control flow construct in J. It applies the verb defined within the parentheses to each element of `x` and then applies the verb `&~x` to the resulting array.

    *3. Verb Body:* * `,/{@[x;y;]'(!10)^x|/p[;y]=p,:,3/:-3!p:!9 9}` is the body of the verb. Let's break it down further: * `{@[x;y;]` creates a gerund (a verb-like noun) that takes two arguments, `x` and `y`. * `'(!10)^x` generates an array of `x` elements, each raised to the power of `!10` (factorial of 10). `/p[;y]=p` is a conjunction that appends the value of `p` to itself for each element in `y`. * `,:,3/:-3!p:!9 9}` generates an array of 3 elements, each of which is the factorial of `-3` (which is undefined and results in an error) followed by the number 9.

    *4. Overall Functionality:* * The verb takes an array `x` as input. * It applies the gerund to each element of `x`, creating an array of arrays. * It then applies the conjunction to each of these arrays, appending the value of `p` (which is likely defined elsewhere in the code) to itself. * Finally, it generates an array of 3 elements with errors and 9s. * The hook `/&~x` applies the verb to each element of `x` and then applies a function that is likely defined elsewhere in the code (since `&~x` is not defined within this verb).

    *Note:* Without more context about the definitions of `p` and other variables or functions used in the code, it's difficult to provide a more precise explanation of the verb's exact behavior. However, the breakdown above should give you a general understanding of the code's structure and logic.

    • alach11 7 hours ago

      For completeness, I tested o1-preview and o1-mini. Both were able to identify the language, but only o1-preview realized it was a sudoku solver.

    • rak1507 11 hours ago

      Please kindly delete your account, destroy your devices, and move to the woods far away from technology.

      • yumraj 10 hours ago

        Sure. but please elaborate ..

        • rak1507 10 hours ago

          I cannot comprehend the mindset of people who decide to spam (because that is what your comment is) any forum with a page of bullshit GPT slop. Do you think it's helpful or interesting?

          • yumraj 10 hours ago

            Personally I believe it is interesting since it shows the current state of the art for the 3 LLMs.

            I was surprised that Claude was able to identify the language and explain the code.

            But, please feel free to downvote my comments. I guess the aggregate in the end will demonstrate whether it was a useful comment or spam + bullshit GPT slop.

            • rak1507 10 hours ago

              It wasn't able to explain the code, it was wrong.

              • yumraj 10 hours ago

                Perhaps you’ll be kind enough to post the explanation as a top level comment.

                It’ll certainly help those of us who do not know K.

wileydragonfly 15 hours ago

Sudoku was always a meditative thing for me. It’s impossible not to win so long as you pay attention. Optimizing solutions seems contrary to the point to me.

  • swatcoder 15 hours ago

    Solvers are useful for confirming that a puzzle you've recieved or generated is solvable. The meditative process can really go sideways when there is no solution for you to stumble upon.

    Puzzles in commercial collections don't usually have that problem, but those from other sources sometimes do.

    Solvers also make for a nice craft exercise, as here. Simple but not trivial, you can approach them in a lot of different ways and thereby work through different techniques or constraints you mean to explore.

    • sellyme 6 hours ago

      > Puzzles in commercial collections don't usually have that problem,

      I would argue that puzzles in commercial collections are more likely to have that problem than ones made freely available by hobbyists, as commercial enterprises inevitably cut corners on things like labour costs for an actual human setter.

      I have seen dozens of commercial puzzle games and applications that do not make any attempt to verify the (auto-generated) puzzles as solvable, but I don't think I've ever had the same problem on a site like LMD.

  • UncleOxidant 15 hours ago

    I guess I'm the opposite. After doing a couple of sudoku many years ago my thought was "Hey, I could just automate this" and started thinking of algorithms.

  • kranner 12 hours ago

    Optimising a Sudoku solver can be seen as a different puzzle entirely and not as a mode of playing Sudoku.

  • teo_zero 9 hours ago

    Interesting position that was not expressed before. However please note that the same could be said about writing a solver.

  • malux85 15 hours ago

    Optimising solutions is the meditative exercise for me.

    I enjoy running simulation after simulation after simulation, studying possible outcomes and optimising everything. Everyone is different :)

  • gerdesj 14 hours ago

    Meta: No need to DV a comment you don't like for no reason. Engage instead. Why not have a chat?

    • ben0x539 14 hours ago

      Wouldn't it be more productive/rewarding to instead engage with comments I do like?

      • otteromkram 12 hours ago

        Only you can say what's best for you.

        If have to ask: What's rewarding about only having your viewpoint reinforced?

        • johnisgood 5 hours ago

          Just under this submission I have upvoted a handful of comments with which I disagreed, mainly because of its replies.

        • ben0x539 11 hours ago

          Where are you getting the viewpoints thing from?

    • swatcoder 14 hours ago

      Downvotes and upvotes work together to manage the visibility of posts that align with the community's tastes.

      While I myself found an opportunity to reply to the GP and didn't down vote them, their comment only engaged with the article in a shallow way and only then, seemingly, to just dismiss the concept of solver altogether.

      It wasn't a offensive comment, but it didn't really contribute to the site in the way many people digging into deep technical walkthroughs like this expect to see.

      Some downvotes weren't guaranteed, but they're not surprising and they're probably helping new readers stay engaged with more topical and technical alternatives.

      It's not the end of the world to get a few downvotes, and it's almost never personal. It certainly isn't here.

      • jksmith 13 hours ago

        Aside: Downvotes on HN can be an expression of age related, self-righteous sniper pique; Opinions on what contributes to a conversation can be all over the place and are entirely subject to biases, which can be interesting (I guess). Doesn't really matter, and Hail Satan anyway. Also "Q for Mortals" is an interesting book.

    • riiii 14 hours ago

      People are saturated with anger and frustration after doom scrolling. They engage with their pitchforks.

      • mcphage 12 hours ago

        A few anonymous downvotes are what qualifies as pitchforks these days?

  • K0balt 14 hours ago

    I find that sodoku is not a math or even a logic puzzle, but rather an epistemology puzzle. Lots of how we know/how much we know, and if you get into speed with some failure tolerance through estimating probability it adds even more thought provoking rabbit holes.