1.  

    8,000 characters in five hours is 1,600 characters per hour, or 27 characters per minute.

    Do we specify the typing speed required by a secretary in words typed per day?

    1. 1

      I did not find this explicitly mentioned, but surely the name resolution in OOP is dynamic rather than lexical?

      1.  

        Depends on the language doesn’t it?

        1.  

          I would argue that message passing, with the objects deciding what to do about a message received at runtime captures the essence of dynamic binding.

          However, I agree with your point. OO is somewhat amorphous at this point, and one may very well implement a language without late binding and call it OO.

          Edit: To clarify what I meant; dynamic binding is where the execution path rather than the lexical ordering determines how a method or variable is resolved. When an object receives a message, the message resolution is determined by the execution path that involved that object. That is, one can not predict in advance using lexical knowledge alone what method will be called.

          1. 8

            The post talks both about name resolution (lexical and dynamic scope) and method resolution, and sometimes seems to conflate the two.

            All mainstream OO languages that I’m familiar with use lexical scope, while most of them use dynamic binding.

            1.  

              Yes, agreed. Got muddled :/

      1.  

        Do people have multiple accounts in different mastodon servers? If not, what is a good home base for someone from lobsters? Does lobsters have a mastodon presence?

        1.  

          Do people have multiple accounts in different mastodon servers?

          Most people are only active on one account, I sometimes see people with two or three accounts, where each account is related to a specific topic. Another thing is people sometimes “move” from one instance to another, by pointing from their old account to their new one, in case they change their mind about an instance (eg. my old account, my current account).

          If not, what is a good home base for someone from lobsters?

          My advice would be to check out a general purposes instance first, unless you are very active in a specific community (eg. BSD Users like https://bsd.network, …). From there start following people you might find a bit interesting, since they will lead you to people you might find more interesting. Pining certain hashtags has helped me too. It takes a bit to get into it, since there is no thorough recommendation system, but then it clicks it’s comfortable – in my case far more than twitter ever was.

          Does lobsters have a mastodon presence?

          There was a thread a while back where people shared their accounts, that’s when I really started using Mastodon.

        1. 5

          On a related note, there used to be a customized Inferno distribution that was just acme + a few bits called acme-sac – a single binary that ran acme on Inferno on fullscreen. I loved that I could run Inferno as my OS and use it as my daily editor with the ability to mount remote filesystems, see current processes in the editor and such (a sort of Emacs on steroids).

          Unfortunately, the project seems to have stalled.

          1. 11

            Similar to Fibonacci, a piece of code that enlightened me was the simple PEG implementation, which is represented as a pair of mutually recursive procedures. I used to think of parsers as really difficult to understand, and hard to write. But the simplicity of PEG was an eye opener.

            def unify_key(key, text, at):
               if key not in grammar:
                   return (True, at + len(key)) if text[at:].startswith(key) else (False, at)
               rules = grammar[key]
               for rule in rules:
                   res, l = unify_rule(rule, text, at)
                   if res: return (res, l)
               return (False, 0)
            
            def unify_rule(rule, text, at):
                for token in rule:
                      result, at = unify_key(token, text, at)
                      if not result: return (False, at)
                return (True, at)
            

            Given a grammar as below, we try to unify the input string with the starting key – here expr. If To unify a key with the given string (unify_key), we check if the key is in the grammar. If it was not, then it is a plain token match, and we do simple string match. If not, we get the production rules defined in the grammar corresponding to the key, and try each rule one by one using unify_rule. We return as soon as any rule succeeds. The unify_rule is also simple. It gets the parts of the rule, and tries to match them in sequence using unify_key. If any of these fails, then return failure.

            grammar = {
                'expr': [
                    ['term', 'add_op', 'expr'],
                    ['term']],
                'term': [
                    ['fact', 'mul_op', 'term'],
                    ['fact']],
                'fact': [
                    ['digits'],
                    ['(','expr',')']],
                'digits': [
                    ['digit','digits'],
                    ['digit']],
                'digit': [[str(i)] for i in list(range(10))],
                'add_op': [['+'], ['-']],
                'mul_op': [['*'], ['/']]
            }
            

            A driver

            import sys
            res, till = unify_key('expr', sys.argv[1], 0)
            assert(till == len(sys.argv[1]))
            print(res)
            

            Using it:

            $ python3 peg.py '1+10/(3+2)'
            True
            $ python3 peg.py '1+10/x(3+2)'
            Assertion failure
            

            While this implementation can have really bad performance due to back tracking, all one needs to do to make it linear is to decorate the procedures with @functools.lru_cache(maxsize=None), which memoizes the parsing, and makes parsing linear. While this does not implement the complete PEG syntax, it implements enough to be complete in terms of the grammars that can be represented (see Ford 2004 for details).

            Edit: Thanks @asrp for finding that the original had issues.

            1. 2

              Tried it with something like

              print unify_rule(['expr'], '1+10/(3+2)', 0)
              

              There seems to be quite a few typos in here

              -   if key not in grammar: return (text[at:].starts_with(key), len(rule))
              +   if key not in grammar: return (text[at:].startswith(key), len(key))
              
              -      if not result: return False
              +      if not result: return (False, 0)
              
              -  return (True, len)
              +  return (True, l)
              

              There must be more errors since it still only matches the first character of the expression.

              I found confusing for both rule names and string token to be encoded as strings. The same goes for concatenation and ordered choice to both be encoded lists.

              Thanks for bringing up this example, though!

              1. 2

                Sorry about that, and thank you so much for taking time to run it. I took the code from an old presentation, and seems I made errors while typing it in.

                I have fixed it.

                1. 1

                  Thanks for the new version! I understand what its trying to do better now.

              2. 1

                Thanks for the example! While PEGs are not familiar to me (I’ll need to look into them), there’s a lot of potential for minds to be blown in the parser world. Playing a few times with parser combinators did exactly that to me - if that’s something that’s not as familiar to you, then here’s a nice example in Scala.

                1. 1

                  The parser combinators are a way to represent PEG directly in code. So you will find them quite familiar. I love combinator based parsing, they are quite powerful and enlightning – A while back, I did a few posts (1, 2, 3, 4, 5, 6, 7) on building a small concatenate language using Parsec (The original monadic combinator library in Haskell) for parsing. You may find them interesting.

              1. 5

                For me, the single piece of code that had the largest impact was the ddmin from Andreas Zeller which is used to isolate failure causing input from much larger input.

                import random
                import string
                
                def complement(s, i, l): return s[:i] + s[i + l:]
                
                def some_complement_is_failing(s, npartitions, testfn):
                    subset_length = len(s) // npartitions
                    items = range(0, len(s), subset_length)
                    complements = (complement(s, i, subset_length) for i in items)
                    return next((i for i in complements if testfn(i)), None)
                
                def update_input(s, npartitions, fn):
                    v = some_complement_is_failing(s, npartitions, fn)
                    if v:  return v, max(npartitions - 1, 2)
                    else:  return s, min(npartitions * 2, len(s))
                
                def ddmin(s, fn):
                    npartitions = 2
                    while s:
                        s, n1 = update_input(s, npartitions, fn)
                        if npartitions == len(s): break
                        npartitions = n1
                return s
                

                Given a failure causing input, it is able to narrow the string down to the simplest sequence of characters necessary to cause the same failure. It is not limited to just strings but to any set of input conditions, and has been extended numerous times – The same algorithm lies behind git bisect. However, the core is still just this much.

                As an example, run the following code: The test succeeds if the input contains “()”. So, we progressively trim the input until we find the smallest input that can cause the test to succeed.

                def test(s):
                    print("%s %d" % (s, len(s)))
                    return set('()') <= set(s)
                
                def fuzzer(): return ''.join(random.choices(string.digits +
                                                            string.ascii_letters +
                                                            string.punctuation, k=1024))
                
                mystr = fuzzer()
                minimized = ddmin(mystr, test)
                print("%s => %s" % (mystr, minimized))
                

                Edit: here is a better ddmin code than the one above. The above is kind of mangled by me.

                1. 3
                  • A high signal to noise ratio, (unlike reddit and even HN, and very much like LTU)
                  • Focused discussion (no jokes and low effort posts unlike reddit and /.).
                  • Small and polite community
                  1. 4

                    @akkartik what are your thoughts on having many little languages floating around?

                    1. 9

                      I see right through your little ploy to get me to say publicly what I’ve been arguing privately to you :) Ok, I’ll lay it out.

                      Thanks for showing me this paper! I’d somehow never encountered it before. It’s a very clear exposition of a certain worldview and way of organizing systems. Arguably this worldview is as core to Unix as “do one thing and do it well”. But I feel this approach of constantly creating small languages at the drop of a hat has not aged well:

                      • Things have gotten totally insane when it comes to the number of languages projects end up using. A line of Awk here, a line of Sed there, makefiles, config files, m4 files, Perl, the list goes on and on. A newcomer potentially may want to poke at any of these, and now (s)he may have to sit with a lengthy manpage for a single line of code. (Hello man perl with your 80+ parts.) I’m trying to find this egregious example in my notes, but I noticed a year or two ago that some core Ruby project has a build dependency on Python. Or vice versa? Something like that. The “sprawl” in the number of languages on a modern computer has gotten completely nuts.

                      • I think vulnerabilities like Shellsock are catalyzing a growing awareness that every language you depend on is a potential security risk. A regular tool is fairly straightforward: you just have to make sure it doesn’t segfault, doesn’t clobber memory out of bounds, doesn’t email too many people, etc. Non-trivial but relatively narrow potential for harm. Introduce a new language, though, and suddenly it’s like you’ve added a wormhole into a whole new universe. You have to guard against problems with every possible combination of language features. That requires knowing about every possible language feature. So of course we don’t bother. We just throw up our arms and hope nothing bad happens. Which makes sense. I mean, do you want to learn about every bone-headed thing somebody threw into GNU make?!

                      Languages for drawing pictures or filling out forms are totally fine. But that’s a narrower idea: “little languages to improve the lives of non-programmers”. When it comes to “little languages for programmers” the inmates are running the asylum.

                      We’ve somehow decided that building a new language for programmers is something noble. Maybe quixotic, but high art. I think that’s exactly wrong. It’s low-brow. Building a language on top of a platform is the easy expedient way out, a way to avoid learning about what already exists on your platform. If existing languages on your platform make something hard, hack the existing languages to support it. That is the principled approach.

                      1. 4

                        I think the value of little languages comes not from what they let you do, but rather what they wont let you do. That is, have they stayed little? Your examples such as Perl, Make etc are those languages that did not stay little, and hence, no longer as helpful (because one has to look at 80+ pages to understand the supposedly little language). I would argue that those that have stayed little are still very much useful and does not contribute to the problem you mentioned (e.g. grep, sed, troff, dc – although even these have been affected by feature creep in the GNU world).

                        Languages for drawing pictures or filling out forms are totally fine. But that’s a narrower idea: “little languages to improve the lives of non-programmers”. When it comes to “little languages for programmers” the inmates are running the asylum.

                        This I agree with. The little languages have little to do with non-programmers; As far as I am concerned, their utility is in the discipline they impose.

                        1. 3

                          On HN a counterpoint paper was posted. It argues that using embedded domain specific languages is more powerful, because you can then compose them as needed, or use the full power of the host language if appropriate.

                          Both are valid approaches, however I think that if we subdivide the Little Languages the distinction becomes clearer:

                          • languages for describing something (e.g. regular expression, format strings, graph .dot format, LaTeX math equations, etc.) that are usable both from standalone UNIX tools, and from inside programming languages
                          • languages with a dedicated tool (awk, etc.) that are not widely available embedded inside other programming languages. Usually these languages allow you to perform some actions / transformations

                          The former is accepted as “good” by both papers, in fact the re-implementation of awk in Scheme from the 2nd paper uses regular expressions.

                          The latter is limited in expressiveness once you start using them for more than just ad-hoc transformations. However they do have an important property that contributes to their usefulness: you can easily combine them with pipes with programs written in any other language, albeit only as streams of raw data, not in a type-safe way.

                          With the little language embedded inside a host language you get more powerful composition, however if the host language doesn’t match that of the rest of your project, then using it is more difficult.

                          1. 3

                            First, a bit of critique on Olin Shivers’ paper!

                            • He attacks the little languages as ugly, idiosyncratic, and limited in expressiveness. While the first two is subjective, I think he misses the point when he says they are limited in expressiveness. That is sort of the point.
                            • Second, he criticizes that a programmer has to implement an entire language including loops, conditionals, variables, and subroutines, and these can lead to suboptimal design. Here again, in a little language, each of these structures such as variables, conditionals, and loops should not be included unless there is a very strong argument for the inclusion of it. The rest of the section (3) is more an attack on incorrectly designed little languages than on the concept of little languages per say. The same attacks can be leveled against his preferred approach of embedding a language inside a more expressive language.

                            For me, the whole point of little languages has been the discipline they impose. They let me remove considerations of other aspects of the program, and focus on a small layer or stage at a time. It helps me compose many little stages to achieve the result I want in a very maintainable way. On the other hand, while embedding, as Shivers observes, the host language is always at hand, and the temptation for a bit of optimization is always present. Further, the host language does not always allow the precise construction one wants to use, and there is an impedance mismatch between the domain lingo and what the host language allows (as you also have observed). For example, see the section 5.1 on the quoted paper by Shivers.

                            My experience has been that, programs written in the fashion prescribed by Shivers often end up much less readable than little languages with pipe line stages approach.

                            1. 1

                              That’s tantalizing. Do you have any examples of a large task built out of little stages, each written in its own language?

                              1. 2

                                My previous reply was a bit sparse. Since I have a deadline coming up, and this is the perfect time to write detailed posts in the internet, here goes :)

                                In an earlier incarnation, I was an engineer at Sun Microsystems (before the Oracle takeover). I worked on the iPlanet[1] line of web and proxy servers, and among other things, I implemented the command line administration environment for these servers[2] called wadm. This was a customized TCL environment based on Jacl. We chose Jacl as the base after careful study, which looked at both where it was going to be used most (as an interactive shell environment), as well as its ease of extension. I prefer to think of wadm as its own little language above TCL because it had a small set of rules beyond TCL such as the ability to infer right options based on the current environment that made life a bit more simpler for administrators.

                                At Sun, we had a very strong culture of testing, with a dedicated QA team that we worked closely with. Their expertise was the domain of web and proxy servers rather than programming. For testing wadm, I worked with the QA engineers to capture their knowledge as test cases (and to convert existing ad-hoc tests). When I looked at existing shell scripts, it struck me that most of the testing was simply invoke a command line and verify the output. Written out as a shell script, these may look ugly for a programmer because the scripts are often flat, with little loops or other abstractions. However, I have since come to regard them as a better style for the domain they are in. Unlike in general programming, for testing, one needs to make the tests as simple as possible, and loops and subroutines often make simple stuff more complicated than it is. Further, tests once written are almost never reused (as in, as part of a larger test case), but only rerun. Further, what we needed was a simple way to verify the output of commands based on some patterns, the return codes, and simple behavior such as response to specific requests, and contents of a few administration files. So, we created a testing tool called cat (command line automation tool) that essentially provided a simple way to run a command line and verify its result. This was very similar to expect[3]. It looked like this

                                wadm> list-webapps --user=admin --port=[ADMIN_PORT] --password-file=admin.passwd --no-ssl
                                /web-admin/
                                /localhost/
                                =0
                                
                                wadm> add-webapp --user=admin --port=[ADMIN_PORT] --password-file=admin.passwd --config=[HOSTNAME] --vs=[VIRTUAL_SERVER] --uri=[URI_PATH]
                                =0 
                                

                                The =0 implies return code would be 0 i.e success. For matching, // represented a regular expression, “” represented a string, [] represented a shell glob etc. Ordering was not important, and all matches had to succeed. the names in square brackets were variables that were passed in from command line. If you look at our man pages, this is very similar to the format we used in the man pages and other docs.

                                Wadm had two modes – stand alone, and as a script (other than the repl). For the script mode, the file containing wadm commands was simply interpreted as a TCL script by wadm interpreter when passed as a file input to the wadm command. For stand alone mode wadm accepted a sub command of the form wadm list-webapps --user=admin ... etc. which can be executed directly on the shell. The return codes (=0) are present only in stand alone mode, and do not exist in TCL mode where exceptions were used. With the test cases written in cat we could make it spit out either a TCL script containing the wadm commands, or a shell script containing stand alone commands (It could also directly interpret the language which was its most common mode of operation). The advantage of doing it this way was that it provided the QA engineers with domain knowledge an easy environment to function. The cat scripts were simple to read and maintain. They were static, and eschewed complexities such as loops, changing variable values, etc, and could handle what I assumed to be 80% of the testing scenarios. For the 80% of the remaining 20%, we provided simple loops and loop variables as a pre-processor step. If the features of cat were insufficient, engineers were welcome to write their test cases in any of perl, tcl, or shell (I did not see any such scripts during my time there). The scripts spat out by cat were easy to check and were often used as recipes for accomplishing particular tasks by other engineers. All this was designed and implemented in consultation with QA Engineers with their active input on what was important, and what was confusing.

                                I would say that we had these stages in the end:

                                1. The preprocessor that provides loops and loop variables.
                                2. cat that provided command invocation and verification.
                                3. wadm that provided a custom TCL+ environment.
                                4. wadm used the JMX framework to call into the webserver admin instance. The admin instance also exposed a web interface for administration.

                                We could instead have done the entire testing of web server by just implementing the whole testing in Java. While it may have been possible, I believe that splitting it out to stages, each with its own little language was better than such a step. Further, I think that keeping the little language cat simple (without subroutines, scopes etc) helped in keeping the scripts simple and understandable with little cognitive overhead by its intended users.

                                Of course, each stage had existence on its own, and had independent consumers. But I would say that the consumers at each stage could chosen to have used any of the more expressive languages above them, and chose not to.

                                1: At the time I worked there, it was called the Sun Java System product line.

                                2: There existed a few command lines for the previous versions, but we unified and regularized the command line.

                                3: We could not use expect as Jacl at that time did not support it.

                                1. 1

                                  Surely, this counts as a timeless example?

                                  1. 1

                                    I thought you were describing decomposing a problem into different stages, and then creating a separate little DSL for each stage. Bentley’s response to Knuth is just describing regular Unix pipes. Pipes are great, I use them all the time. But I thought you were describing something more :)

                                    1. 1

                                      Ah! From your previous post

                                      A line of Awk here, a line of Sed there, makefiles, config files, m4 files, Perl, the list goes on and on … If existing languages on your platform make something hard, hack the existing languages to support it. That is the principled approach.

                                      I assumed that you were against that approach. Perhaps I misunderstood. (Indeed, as I re-read it, I see that I have misunderstood.. my apologies.)

                                      1. 1

                                        Oh, Unix pipes are awesome. Particularly at the commandline. I’m just wondering (thinking aloud) if they’re the start of a slippery slope.

                                        I found OP compelling in the first half when it talks about PIC and the form language. But I thought it went the wrong way when it conflated those phenomena with lex/yacc/make in the second half. Seems worth adding a little more structure to the taxonomy. There are little languages and little languages.

                                        Languages are always interesting to think about. So even as I consciously try to loosen their grip on my imagination, I can’t help but continue to seek a more steelman defense for them.

                            2. 2

                              Hmm, I think you’re right. But the restrictions a language imposes have nothing to do with how little it is. Notice that Jon Bentley calls PIC a “big little language” in OP. Lex and yacc were tiny compared to their current size, and yet Jon Bentley’s description of them in OP is pretty complex.

                              I’m skeptical that there’s ever such a thing as a “little language”. Things like config file parsers are little, maybe, but certainly by the time it starts looking like a language (as opposed to a file format) it’s well on its way to being not-little.

                              Even if languages can be little, it seems clear that they’re inevitably doomed to grow larger. Lex and Yacc and certainly Make have not stood still all these years.

                              So the title seems a misnomer. Size has nothing to do with it. Rust is not small, and yet it’s interesting precisely because of the new restrictions it imposes.

                            3. 3

                              I use LPeg. It’s a Lua module that implements Parsing Expression Grammars and in a way, it’s a domain specific language for parsing text. I know my coworkers don’t fully understand it [1] but I find parsing text via LPeg to be much easier than in plain Lua. Converting a name into its Soundex value is (in my opinion) trivial in LPeg. LPeg even comes with a sub-module to allow one to write BNF (here’s a JSON parser using that module). I find that easier to follow than just about any codebase you could present.

                              So, where does LPeg fall? Is it another language? Or just an extension to Lua?

                              I don’t think there’s an easy answer.

                              [1] Then again, they have a hard time with Lua in general, which is weird, because they don’t mine Python, and if anything, Lua is simpler than Python. [2]

                              [2] Most programmers I’ve encountered have a difficult time working with more than one or two languages, and it takes them a concerted effort to “switch” to a different language. I don’t have that issue—I can switch among languages quite easily. I wonder if this has something to do with your thoughts on little languages.

                              1. 2

                                I think you are talking about languages that are not little, with large attack surfaces. If a language has a lengthy man page, we are no longer speaking about the same thing.

                                Small configuration DSLs (TOML, etc), text search DSLs (regex, jq, etc), etc are all marvelous examples of small languages.

                                1. 1

                                  My response to vrthra addresses this. Jon Bentley’s examples aren’t all that little either.[1] And they have grown since, like all languages do.

                                  When you add a new language to your project you aren’t just decorating your living room with some acorns. You’re planting them. Prepare to see them grow.

                                  [1] In addition to the quote about “big little language”, notice the “fragment of the Lex description of PIC” at the start of page 718.

                                  1. 1

                                    What, so don’t create programming languages because they will inevitably grow? What makes languages different from any other interface? In my experience, interfaces also tend to grow unless carefully maintained.

                                    1. 2

                                      No, that’s not what I mean. Absolutely create programming languages. I’d be the last to stop you. but also delete programming languages. Don’t just lazily add to the pile of shit same as everybody else.

                                      And yes, languages are exactly the same as any other interface. Both tend to grow unless carefully maintained. So maintain, dammit!

                            1. 3

                              Does the paper show any further vulnerabilities than that from the paper “OpenJDK’s Java.utils.Collection.sort() is broken: The good, the bad and the worst case.” by Stijn De Gouw et al. 2015.? (cited in this paper too.)

                              1. 2

                                Is a page lost after 713? The continuation after “These routines are rather primitive; more clever “… is not found in 714

                                1. 9

                                  As a /. refugee from the time dinosaurs walked the earth, somehow HN never clicked for me enough to want an account there. Lobsters did. Somehow, for me, Lobsters comes across as a more friendly community than HN.

                                  1. 6

                                    Indeed.

                                    I get the underlying current on HN, that if I’m not making money for myself or helping someone else make money, I’m a waste of comment and air. The moderation seems to be generally in that direction as well. I’d call it as the impetus of being a venture capitalist firm’s media arm. Then again, the larger their “community” gets, the more trolls and bad people will move in. And since it does have to do with capital-Money, trolls are guaranteed.

                                    Admittedly, I post less here primarily because I don’t have as much to add to the technical articles.

                                    1. 0

                                      Very much same, I blocked hacker news in my hosts file and browsing the web has gotten to be a friendlier and less pretentious experience.

                                    1. 2

                                      Are there any technologies that is in Oracle Solaris 11 that is not there in OpenIndiana at this point?

                                      1. 2

                                        There was time when OpenZFS did not had encryption support and Oracle Solaris ZFS had it, but now its implemented, not yet pushed into latest OpenIndiana release but its in the upstream Illumos source and it will also be available on FreeBSD, Linux, macOS and other Illumos distributions.

                                        Currently its quite opposite, OpenZFS version has more features then Oracle ZFS, while device removal is available at both the OpenZFS also has ability to add a driver to RAIDZ (for example from 5 drives to 6 drives) the new DRAID implementation is in the works - similar to what is available on IBM Storwize V7000 or HPE 3PAR enterprise storage arrays, also ZSTD compression will be available on OpenZFS and not on Oracle ZFS …

                                        1. 1

                                          ZFS encryption is not yet available in the illumos source, as people are still working out issues with it.

                                        2. 2

                                          Kernel Zones, immutable zones, DTrace/mdb DWARF support.

                                        1. 3

                                          I find R Studio notebooks (Rmd) to be better than Jupyter notebooks. My reasons are:

                                          1. A transparent markdown format unlike the JSON for jypyter notebooks
                                          2. No state (or at least not as dependent on state as Jupyter)
                                          3. Gives you almost the same interface (support multiple languages including bash, python etc.)
                                          4. Fast!
                                          1. 2
                                            1. First-class support for rendering to a report/immutable form. I like having one version of the source code, with earlier versions in version control; but I also like having analyses side-by-side in a folder, for easy comparison. Rendered reports give me both.

                                            (Jupyter does support rendering to HTML. Rmd lets you write the text in, and render chunk outputs to, LaTeX, Sweave, HTML, Listings, Markdown, Jekyll, and ReStructuredText.)

                                          1. 3

                                            Cryptographers love mod because when you use it with really large numbers you can create what are known as *one-way functions. * These are special functions which allow you to easily calculate something in one direction, but not reverse it.

                                            If I tell you that 9 is the result of my squaring operation, you can easily deduce that the input was 3. You would have the entire process front to back. If I tell you that 9 is the result of my function mod 29, you would have a harder time trying to figure out what the input was.

                                            This gives the wrong idea about one-way functions. For something to be one-way, one should not be able to compute any answers to the question (not just the one the questioner intended). For example, 9 is an answer to your question, which is easy to compute.

                                            1. 4

                                              Here is my technical blog. However, the updates are sporadic.

                                              1. 2

                                                It is a really nice tool. However, when the authors say it is complementary to R, I wonder what miller can do that can’t be done with the same ease in R using hadleyverse. Here is the equivalent of the initial example.

                                                read.csv(‘flins.csv’) %>% mutate(tiv_delta=tiv_2012-tiv_2011) %>% select(-one_of(‘tiv_2011’,‘tiv_2012’)) %>% arrange(tiv_delta)

                                                compared to

                                                mlr –icsv –opprint –barred
                                                put ‘$tiv_delta = $tiv_2012 - $tiv_2011; unset $tiv_2011, $tiv_2012’
                                                then sort -nr tiv_delta flins.csv

                                                1. 4

                                                  I’m surprised this doesn’t use sixels to get real graphics:

                                                  https://github.com/saitoha/libsixel

                                                  1. 6

                                                    The author comments here.

                                                  1. 15

                                                    I’ve become more and more disillusioned with NixOS over the past couple of months. Packaging things that aren’t available, or even updating existing packages, has so many little undocumented gotchas that (I guess) they assume you’ll figure out reading from reading gh issues or random blog posts. It has actually stopped me working on a few different projects because it’s not worth figuring out how to package something.

                                                    However, I don’t think I can go back to a traditional distro after tasting the stability and convenience of something like NixOS. Has anyone here tried both NixOS and GuixSD. or perhaps switched from one to the other?

                                                    Guix seems so much better documented from the brief read though I’ve given it after seeing this. The docs just have so much detail.

                                                    Also, I’d much rather learn a real language like scheme for making packages than the rather incomprehensible (at least to me) language that Nix invented.

                                                    What are the downsides of Guix that I just haven’t seen yet?

                                                    1. 9

                                                      Guix has fewer packages, because they have a smaller community. Being a GNU project, they attempt to limit the amount of non-free, or license-incompatible, software as much as possible: using linux-libre, nearly no potential ZFS support, no Intel microcode, etc. If your hardware depends on a binary blob, you might have to jump through several hoops to get it working. As of 2018-07-06, they don’t have LVM support.

                                                      That said, guix seems far better thought out than nix. It does not rely on a particular init ecosystem (cough, systemd, cough). It has more features available without installing additional packages, for example: guix import instead of the myriad of pypi2nix, nix-generate-from-cpan, etc packages that are separately written; guix environment makes creating an isolated container as easy as its normal environment isolation; etc. And guix is most certainly better documented.

                                                      If you’re comfortable packaging software yourself (and don’t mind doing so), some of these problems could be fixable. You can keep (or contribute to) a non-free guix repository (such as these, but these do not seem to be well maintained, nor will the be approved of, probably). One could also use guix import to import from a local copy of nixpkgs (though such an import is imperfect, and might require manual maintenance), or run guix atop NixOS.

                                                      Unfortunately, I needed a system that works with nearly-minimal hassle on my hardware, with my software, and that is what NixOS gave me. The nix language is quaint, and the reliance on bash and systemd rather annoying, but personally I can ignore that and use a working computer with a relatively nice environment management system.

                                                      1. 2

                                                        It does not rely on a particular init ecosystem You are referring to Guix, the package manager here, right? Because, as far as I understand, GuixSD, the Linux distribution does depend on https://www.gnu.org/software/shepherd/?

                                                        1. 3

                                                          I was referring to the fact that neither Guix nor GuixSD rely on systemd. But you are correct, as best as I can tell GuixSD seems to rely on Shepherd.

                                                          Though maybe not all services seem to rely on it? Some of them don’t seem to mention shepherd at all, but I can’t tell whether or not that means anything because I’m not well versed in Guix scheme.

                                                          1. 1

                                                            https://github.com/guix-mirror/guix/blob/master/gnu/services/ssh.scm

                                                            Here’s one example that clearly refers to shepherd. Is there any reason to believe that shepherd is better than systemd?

                                                            1. 6

                                                              Three things, maybe:

                                                              • Shepherd doesn’t try to be more than an init system. Contrast to Logind, which GNOME depends on, which is tied to systemd. elogind had to be forked and extracted from systemd, because otherwise GNOME would not work without it. I don’t know of any end user applications that require shepherd to be the init system in any way that doesn’t resemble init system / daemon management usage.
                                                              • shepherd is also written in scheme, which means that Guix expressions can easily generate code per the user’s configuration for the shepherd file since you’re just going from scheme to scheme.
                                                              • I can’t remember if systemd can do this or not, but you can also run shepherd as a user to manage your user’s daemons (rather than the system-wide daemons). Convenient!
                                                              1. 1

                                                                I can’t remember if systemd can do this or not, but you can also run shepherd as a user to manage your user’s daemons

                                                                Yes, systemd can do that.

                                                                1. 1

                                                                  I can’t remember if systemd can do this or not, but you can also run shepherd as a user to manage your user’s daemons

                                                                  Systemd does have support for user services, without needing to start another daemon as your user.

                                                                  1. 1

                                                                    I should clarify that I meant being able to run one or more shepherd as a user being a feature :)

                                                                2. 5

                                                                  Shepherd isn’t an ecosystem of things that come bundled together? It isn’t Linux specific? It doesn’t (yet) slowly overtake various other components of your system, such as udev? There are definitely reasons that I still believe that Shepherd is better than systemd.

                                                                  However, nothing’s perfect. Upon a further examining of the documentation, it does seem that you are correct regarding Guix’s dependence on Shepherd: namely, all services do currently depend on it.

                                                            2. 2

                                                              Thanks for that Guix on NixOS link. I actually installed GuixSD in a VM at work today and noticed there were quite a few packages missing that I would like to have, so that seems like a good way to get started making son new packages before I go all in on the OS.

                                                              1. 1

                                                                What is the status of Java especially maven dependencies of a project? (which doesn’t seem to be fixed in Nix yet)?

                                                            1. 2

                                                              looks like a decent alternative to mcabber, but I really hope this trend of “git clone and run a mystery shell script” ends soon. we have trusted build systems and package distribution systems; we should use them.

                                                              1. 3

                                                                That’s for running the developer branch only. Linux Distributions and *BSDs have it packaged.

                                                                1. 1

                                                                  Yeah. I was going to build it because I didn’t know if it was in the repos of my distribution (Fedora), however I found that it was.

                                                                2. 1

                                                                  Most package distribution systems assume root (except for a few such as Nix variants and pkgsrc AFAIK). I don’t see why I should prefer such a distribution especially when the intent is to try it out first.

                                                                  1. 1

                                                                    mcabber. Never heard of it. I can check it out but since I am becoming accustomed to poezio Idk.

                                                                    I see they look similar hence I will probably stay with poezio.

                                                                    1. 1

                                                                      You mean like these package distribution systems?

                                                                    1. 1

                                                                      Can you at least identify the type information for these functions? If you have type information, and you have the ability to identify plausible bounds for the primitive types, you can rely on sampling to some extant to get reasonably high confidence that two functions that take similar types of arguments are the same. The good news is that pathological cases usually occur in with values that are reasonably small see small scope hypothesis. Further, if you rely on statistical sampling, you can be have a statistically high confidence after sampling a constant number of inputs (under certain assumptions).