95 Matching Annotations
  1. Last 7 days
    1. So it is design. You are solving constrained problems by creating your own constraints, and you are designing that something to be executed. So it is very much a design problem.

      per previously introduced definition of design something to be executed

  2. Nov 2019
    1. They answer the two chief complaints about Lisp syntax: too many parentheses and “unnatural” ordering

      they do that, but I don't think that's their primary rationale and a deeper win more important they neatly express certain structure / shape of computation

    1. I wonder, what else do we need files for?

      interestingly with it's then new mobile devices that's what apple thought! they came to this from ui / "sales" perspective though

    2. Querying a database for Jan 1994 sales, and clicking on folders "Sales", "1994", "January" are very related activities. Why can't a "real" database then take over a file system entirely?

      the clicking on folder is probably the answer why, it's something that's tied closely to it's user interface

  3. Oct 2019
    1. In 2017, I rewrote it again as a ClojureScript application, and it was only 500 lines of code! Holy cow!!!

      going from 3k obj-c to 1,5k js to 0.5k in cljs!

    1. For example the following pattern: (let [x true y true z true] (match [x y z] [_ false true] 1 [false true _ ] 2 [_ _ false] 3 [_ _ true] 4)) ;=> 4 expands into something similar to the following: (cond (= y false) (cond (= z false) (let [] 3) (= z true) (let [] 1) :else (throw (java.lang.Exception. "No match found."))) (= y true) (cond (= x false) (let [] 2) :else (cond (= z false) 3 (= z true) 4 :else (throw (java.lang.Exception. "No match found.")))) :else (cond (= z false) (let [] 3) (= z true) (let [] 4) :else (throw (java.lang.Exception. "No match found.")))) Note that y gets tested first. Lazy pattern matching consistently gives compact decision trees. This means faster pattern matching. You can find out more in the top paper cited below.
  4. Sep 2019
    1. The problem with the annotation notion is that it's the first time that we consider a piece of data which is not merely a projection of data already present in the message store: it is out-of-band data that needs to be stored somewhere.

      could be same, schemaless datastore?

    2. many of the searches we want to do could be accomplished with a database that was nothing but a glorified set of hash tables

      Hello sql and cloure.set ns! ;P

    3. There are objects, sets of objects, and presentation tools. There is a presentation tool for each kind of object; and one for each kind of object set.

      very clojure-y mood, makes me think of clojure REBL (browser) which in turn is inspired by the smalltalk browser and was taken out of datomic (which is inspired by RDF, mentioned above!)

    1. That said, most Clojure programs begin life as text files, and it is the task of the reader to parse the text and produce the data structure the compiler will see

      clojure compiler sees (real) clojure i.e. programs as clojure data structures (we) humans see clojure in their (semi-incidental) representation in text readers bridges the gap

      Now, why semi- incidental? It's not necessary for clojure to be text but it is necesserry for it to be represented as some kind of symbolic representations for humans. It's pretty much always text

    1. Providing a medium-resolution view might seem like a pretty minor benefit, but the power is that *you control the resolution.* It's like an adjustable slider you can fine tune, instead of a dial with two settings: 1 (tags) and 10 (search)

      YES!

    2. Search has words or terms as the unit of resolution, which are often too specific to be useful (it doesn't help me much to know that a note contains the word "neuroscience")

      "Search" (text based) doesn't BUT more powerful methods of search are possible

      • metadata
      • regex
      • full blown query language
    3. Progressive summarization splits the difference, highlighting the most important ideas, but crucially, nested within the context that allows them to stand on their own as useful building blocks

      This is in line with what I think BUT I would like to have that to be somewhat automatic

      The goals might be different here Progressive summarisations is focused on /a document/

      • making sense of that document
      • recall of the information later

      My goal is focusing on networks of ideas, finding connections, initial research of some topic OR serendipity

    4. Tags have topics or themes as the unit of resolution, which are often too broad to be useful (it doesn't help me much to know that a note has something to do with neuroscience)

      it doesn't help with understanding BUT it helps with serach and creating connections

  5. Aug 2019
    1. After the success of MORE, he went on to develop a scripting language whose syntax (for both code and data) was an outline. Kind of like Lisp with open/close triangles instead of parens! It had one of the most comprehensive implementation of Apple Events client and server support of any Mac application, and was really useful for automating other Mac apps, earlier and in many ways better than AppleScript.

      Yes, lisp!

      This is my thinking as well i.e. if you could (a) keep parentheses but render them differently. But not going over board in basic view so it's still editable like text. AND also have a more graphical view.

    2. After the success of MORE, he went on to develop a scripting language whose syntax (for both code and data) was an outline.

      Lisp! ;P

    3. More was great because it had a well designed user interface and feature set with fluid "fahrvergnügen" that made it really easy to use with the keyboard as well as the mouse. It could also render your outlines as all kinds of nicely formatted and stylized charts and presentations. And it had a lot of powerful features you usually don't see in today's generic outliners.

      fahrvergnügen German for "driving-pleasure. Yes! ALSO This is kind of central, in two ways.

      A. you need to have good story for mouse only and keyboard only B. you need to have multi-modal rendering

    4. Engelbart also showed how to embed lists and outlines in maps:https://www.youtube.com/watch?v=yJDv-zdhzMY&t=15m39s

      Now this is interesting. Instead of normal map here they've had to use this simple sketch/graph. Just arrows etc. BUT There maybe an actual value in that kind of simplicity!

      Question worth asking here is why we have to see all the detail on the map always? Google may have different incentives than just showing you only essential data.

  6. Jul 2019
    1. Compusophic Systems

      those old school tech companies names! compu-sophic! computer - philosophic

  7. Jun 2019
    1. Entities are the applications, services, and files in the ARGON worldview

      smalltalk objects

    1. total jerks. As the leader of a popular OSS project, in one way or the other you’ll have to confront with these people, and that’s maybe one of the most stressful things I ever did in the course of the Redis development.

      what's the way to shield yourself from that? This is stresfull mostly because this is not who he (or I) is... i.e. person equipped to deal with this kind of relations

  8. May 2019
    1. Although regular macros work on programs in the form of trees, a special type of macro, called a read macro, operates on the raw characters that make up your program.

      this make me wonder how is this different from pre-processors? if I'm working on text before compile, is being in the same language giving me any advantage

    2. Not only does lisp provide direct access to code that has been parsed into a cons cell structure, but it also provides access to the characters that make up your programs before they even reach that stage.

      reader macros user extendible read macros are not present in clojure there is a project to provide that outside vanilla clojure

  9. develop.spacemacs.org develop.spacemacs.org
    1. Set the layer variable org-projectile-file to the filename where you want to store project-specific TODOs. If this is an absolute path, all todos will be stored in the same file (organized by project), whereas if it is just a single filename, todos will be stored in each project root. (setq-default dotspacemacs-configuration-layers '((org :variables org-projectile-file "TODOs.org")))

      could use dir_locals to set it per project?

    1. I want to stop putting comments in my code. I want it to be first-class for my code to be in the left pane and my comments to be in the right pane, always binded together with anchors but always separate so my comments don't have to adhere to the limitations of the code's text area.

      emacs--annotate.el

  10. Apr 2019
    1. deps.edn - install level deps.edn file, with some default deps (Clojure, etc) and provider config

      /usr/local/Cellar/clojure/<version> for brew installed

    1. :deps ; to get access to clojure.tools.deps.alpha.repl/add-lib ;; - now you can add new deps to a running REPL: ;; (require '[clojure.tools.deps.alpha.repl :refer [add-lib]]) ;; (add-lib 'some/library {:mvn/version "RELEASE"}) ;; - and you can git deps too; here's how to get the master version of a lib: ;; (require '[clojure.tools.gitlibs :as gitlibs]) ;; (defn load-master [lib] ;; (let [git (str "https://github.com/" lib ".git")] ;; (add-lib lib {:git/url git :sha (gitlibs/resolve git "master")}))) ;; - e.g., using the GitHub path (not the usual Maven group/artifact): ;; (load-master 'clojure/tools.trace) {:extra-deps {org.clojure/tools.deps.alpha {:git/url "https://github.com/clojure/tools.deps.alpha" :sha "e160f184f051f120014244679831a9bccb37c9de"}}}

      add-lib etc

    2. ;; - see https://github.com/bhauman/rebel-readline ;; - start a Rebel Readline REPL: :rebel {:extra-deps {com.bhauman/rebel-readline {:mvn/version "RELEASE"}} :main-opts ["-m" "rebel-readline.main"]}

      run bh's rebel from anywhere

    1. However, we found a few trade-offs when using clojure.spec: clojure.spec requires registering a spec for each key in every path that you care about in a data structure, which can be verbose, especially for deeply-nested data structures. We felt this pain the most when specifying the incoming webhook payloads from the providers. We didn't specify the full payloads, we only specified the values that we actually needed, some of which were nested 7-8 levels deep. To work around this, we used data-spec (part of the spec-tools project) to define the payload specs as a mirror of the shape of the actual data. clojure.spec's error output is concise, and it's not always immediately apparent where the validation failure is within the data, especially when validating a large data structure. To help with this, we used expound to generate friendlier error messages at the REPL and in tests.

      spec gotchas

    2. This system is the first significant project on which we have used clojure.spec, and it proved useful in a few ways: Specifying the inputs to each layer in one place made it easier to visualize the shape of the data as it flowed through the subsystem, and proved valuable when describing the behavior to other engineers.Instrumenting the inputs and outputs of our layer boundary functions (via Orchestra), during testing, enabled us to quickly catch cases where we deviated from the spec, allowing us to see the issue at that boundary instead of as a random error within the implementation. Validating the layer inputs against our specs in production allows us to quickly diagnose and isolate faults to the layer where it was triggered, and helps us catch when our assumptions about the shape of the webhook event are incorrect. Having specs allowed for more straightforward tests, since we didn't need to assert on the shape of the data.

      benefits of spec

    1. ([a b] (if (and (map? a) (map? b)) (merge-with deep-merge a b) b))

      deep-merge nice recursive solution piggybacking on merge-with

    2. ([m k f] (if-let [kv (find m k)] (assoc m k (f (val kv))) m))

      update-existing good use of find & combination of if-let and find!

    3. ([pred coll] (reduce (fn [_ x] (if (pred x) (reduced x))) nil coll))

      find-first

    1. (def current "Get current process PID" (memoize (fn [] (-> (java.lang.management.ManagementFactory/getRuntimeMXBean) (.getName) (string/split #"@") (first)))))

      getting current proces id (PID) more importantly: java.lang.management.ManagementFactory/getRuntimeMXBean

    1. (defn- file? [f] (instance? java.io.File f)) (defn- find-files-in-dir [dir] (filter #(.isFile ^File %) (file-seq dir)))

      finding files nice declarative way file-seq of this dir

    1. (s/def :ring.http/field-name (-> (s/and string? not-empty field-name-chars?) (s/with-gen #(gen/not-empty (gen-string field-name-chars)))))

      clean way of using with gen!

    2. (defn- gen-string [chars] (gen/fmap str/join (gen/vector (gen/elements chars)))) (defn- gen-query-string [] (->> (gen/tuple (gen/not-empty (gen/string-alphanumeric)) (gen-string uri-chars)) (gen/fmap (fn [[k v]] (str k "=" v))) (gen/vector) (gen/fmap #(str/join "&" %)))) (defn- gen-method [] (gen/fmap keyword (gen/not-empty (gen-string lower-case-chars)))) (defn- gen-input-stream [] (gen/fmap #(java.io.ByteArrayInputStream. %) (gen/bytes))) (defn- gen-exception [] (gen/fmap (fn [s] (Exception. s)) (gen/string-alphanumeric)))

      nice lesson on generators

    3. (defn- char-range [a b] (map char (range (int a) (inc (int b))))) (def ^:private lower-case-chars (set (char-range \a \z)))

      nice way of defining character range

  11. Mar 2019
  12. Feb 2019
    1. :ok

      nice, return value: keyword!

    2. (fn [system] (throw (ex-info "initializer not set, did you call `set-init`?" {}))))

      interesting pattern, default function throws kind of like abstract base classes methods in python

  13. Dec 2018
    1. Full disclosure: I’m a co-maintainer of clj-time and I’m pretty vocal about encouraging people not to use clj-time when starting a new project: use Java Time instead. Conversion from an existing, clj-time-heavy project is another matter tho’, unfortunately.

      sean cornfield co-mainainter of clj-time use Java.Time

  14. Nov 2018
    1. Meditation can not only provide a welcome counterweight to this work with abstractions, it also cultives 10 qualities of character (Pali: paramis) that are useful during the practice of programming.

      Generosity Morality Renunciation Understanding Effort Patience/tolerance Truthfulness Loving-kindness Equanimity

    1. One quick trick for making it easier for debugging/understanding your threading macros is to put print statements in between some of the steps. The important thing to remember is that all the print functions in clojure return nil so you need to make a little helper function (I like to call mine ?) that prints and then returns the original input, like this: (defn ? [x] (prn x) x)

      debugging trick

    2. I don't think passing the entire http client is very idiomatic, but what is quite common is to pass the entire "environment" (aka runtime configuration) that your app needs through every function. In your case if the only variant is the URL then you could just pass the URL as the first parameter to get-data. This might seem cumbersome to someone used to OO programming but in functional programming it's quite standard. You might notice when looking at example code, tutorials, open source libraries etc. that almost all code that reads or writes to databases expects the DB connection information (or an entire db object) as a parameter to every single function. Another thing you often see is an entire "env" map being passed around which has all config in it such as endpoint URLs.

      passing state down the call stack configuration, connection, db--pretty common in FP

    3. Something that I've found helps greatly with testing is that when you have code with lots of nested function calls you should try to refactor it into a flat, top level pipeline rather than a calling each function from inside its parent function. Luckily in clojure this is really easy to do with macros like -> and friends, and once you start embracing this approach you can enter a whole new world of transducers. What I mean by a top level pipeline is that for example instead of writing code like this: (defn remap-keys [data] ...some logic...) (defn process-data [data] (remap-keys (flatten data))) (defn get-data [] (let [data (http/get *url*)] (process-data data))) you should make each step its own pure function which receives and returns data, and join them all together at the top with a threading macro: (defn fetch-data [url] (http/get url)) (defn process-data [data] (flatten data)) (defn remap-keys [data] ...some logic...) (defn get-data [] (-> *url* fetch-data process-data remap-keys)) You code hasn't really changed, but now each function can be tested completely independently of the others, because each one is a pure data transform with no internal calls to any of your other functions. You can use the repl to run each step one at a time and in doing so also capture some mock data to use for your tests! Additionally you could make an e2e tests pipeline which runs the same code as get-data but just starts with a different URL, however I would not advise doing this in most cases, and prefer to pass it as a parameter (or at least dynamic var) when feasible.

      testing flat no deep call stacks, use pipelines

    4. One thing Component taught me was to think of the entire system like an Object. Specifically, there is state that needs to be managed. So I suggest you think about -main as initializing your system state. Your system needs an http client, so initialize it before you do anything else

      software design state on the outside, before anything else lessions from Component

    5. For the sweet spot you're looking for, I suggest being clear about if you're designing or developing. If you're designing and at the REPL, force yourself to step away with pen and paper after you've gotten some fast feedback.

      designing vs developing!

    1. n

      Using the syntax #'a.b/d is a shortcut for (var a.b/d), with returns the "var" which points to the "function" a.b/d. When Clojure sees the var, it automatically substitutes the function before evaluation. I found this (mostly undocumented) behavior quite confusing for several years. – Alan Thompson May 26 '16 at 21:41

    1. Re-open libraries for exploration I use in-ns to jump into library namespaces and re-define their vars. I insert bits of println statements to help understand how data flows through a library. These monkey-patches only exist in the running REPL. I usually put them inside a comment form. On a REPL restart, the library is back at its pristine state. In this example below, I re-open clj-http.headers to add tracing before the header transformation logic: [source] ;; set us up for re-opening libraries (require 'clj-http.headers) (in-ns 'clj-http.headers) (defn- header-map-request [req] (let [req-headers (:headers req)] (if req-headers (do (println "HEADERS: " req-headers) ;; <-- this is my added print (-> req (assoc :headers (into (header-map) req-headers) :use-header-maps-in-response? true))) req))) ;; Go back to to the user namespace to test the change (in-ns 'user) (require '[clj-http.client :as http]) (http/get "http://www.example.com") ;; This is printed in the REPL: ;; HEADERS: {accept-encoding gzip, deflate} An astute observer will notice this workflow is no different from the regular clojure workflow. Clojure gets out of your way and allows you to shape & experiment in the code in the REPL. You can use this technique to explore clojure.core too!

      explore library code in the repl in-ns and the redefinition

    2. Unmap namespaces during experimentation I use ns-unmap and ns-unalias to remove definitions from my namespace. These are the complementary functions of require and def. While exploring, you namespace will accrue failed experiments, especially around naming. Instead of using a giant hammer [tools.namespace], you can opt for finer-grained tools like these. Example: (require '[clojure.string :as thing]) (ns-unalias *ns* 'thing) ; *ns* refers to the current namespace

      cleaning up the namespace fro repl experimentation

    1. But hey, we're not running Windows 95 anymore! The current branch of windows is based on Windows NT, not Win95. But Windows NT wanted compatibility with DOS/Windows programs. And XP merged the two lines. So these special files still work, FORTY FOUR FUCKING YEARS LATER

      special files today 44 years later--backwards compatibility

    2. This idea was brought into CP/M by Gary Kiddal in 1974. You could do neat things with it like copy data off the serial port into a text file, or print a textfile right from the command line! This is done in unix by having special files existing in special folders, like /dev/tty for the console or /dev/lp0 for the first printer. You can get infinite zeros from /dev/zero, random bytes from /dev/random, etc! but here's the problem: CP/M is designed for 8-bit computers with very little memory, and no hard drives. At best you've got an 8" floppy drive. So directories? you don't need 'em. Instead of directories, you just use different disks. but without directories you can't put all your special files over in a /dev/ directory. So they're just "everywhere", effectively. So if you have FOO.TXT and need to print it, you can do "PIP LST:=FOO.TXT" which copies foo.txt to the "file" LST, which is the printer. and it works where ever you are, because there are no directories! it's simple. but what about extensions? Here's the problem: programs like to name their files with the right extension. so if you're running a program and it goes "ENTER FILENAME TO SAVE LISTING TO" you could tell it LST to print it or PTP to punch it out to tape (cause it's 1974, remember?) but the program might try to put .TXT on the end of your filename! LST.TXT isn't the printer, right? Nah. It is. These special devices exist at all extensions, so that this works. so if "CON" is reserved to refer to the keyboard, so is CON.TXT and CON.WAT and CON.BUG

      special files in cp/m

    1. That is using a specific tool for a specific use case. You don’t actually have a table view of your data. Once it’s in a table, man, you’re good. That is the modeling. A sequel database table, you have this amazing high-level language for doing all sorts of cool operations with it.To turn this into some class hierarchy, it’s almost criminal. There, I said it. It’s like you’re throwing away the power that you have.

      about a situation when you sometime want an is-a relationship but in most cases just have it as loosely structured (table-like) data format

    1. in general, clojure doesn't have java interop, it has jvm interop so in places where the java language doesn't map 1:1 to the jvm, clojure gives something that matches the raw jvm, not something that matches the java language

      jvm not java interop

    2. clone the repo, then lein install and use whatever that snapshot version in project.clj is where you want to use it (edited)

      how to use specific version of library you can also use checkouts where you just symlink to a local copy from your-project/checkouts

    1. This means that software that deals with Internet must be actively maintained. If it is not it will become more and more useless in practice over time, however much it remains theoretically correct, not because it has bugs or security holes as such but because the environment it was designed to work in no longer exists and thus the assumptions it was built on are now incorrect.

      internet software decays

    1. I update from within Spacemacs by opening a file from .emacs.d, usually the readme file.SPC g s to open Magit client, F to bring up the pull menu, -r to set rebase to true, o to pull from origin.  Then I restart Spacemacs with SPC q r.Then I update the .spacemacs file from template.  And then update packages from the link on the Spacemacs home buffer SPC b h (edited)

      update procedure for spacemacs

  15. Oct 2018
    1. If you haven't experienced the glory of wool, get this shirt. I wear it every day for at least two to three weeks before washing it, stains magically disappear (I've already spilled chocolate on this one, haven't washed it yet, and there's no sign), doesn't ever smell bad, dries quickly, etc. Honestly, wearing cotton strikes me as a bit barbaric.

      wear wool

    2. I've been more or less a nomad since 2008, and was one of the very first to really travel in a minimalist (one small backpack) way. I'm sure others came before me (and my friend Todd), but none I'm aware of who were writing about it.

      first nomad, yeah!

    1. Engelbart embedded a set of organizing principles in his lab, which he termed "bootstrapping strategy".
    2. Engelbart's career was inspired in December 1950 when he was engaged to be married and realized he had no career goals other than "a steady job, getting married and living happily ever after".[14] Over several months he reasoned that: he would focus his career on making the world a better place[15] any serious effort to make the world better would require some kind of organized effort that harnessed the collective human intellect of all people to contribute to effective solutions. if you could dramatically improve how we do that, you'd be boosting every effort on the planet to solve important problems – the sooner the better computers could be the vehicle for dramatically improving this capability.[14]

      Engelbart's guiding philosophy

    1. In computer programming, it doesn’t have a very complex definition. It just means that you represent a thing as part of your data model.

      definition of reify in compsci

    1. A lot of this would be a non issue if we had end user programming. The problem today is that 'configurability' is itself something the programmer needs to implement

      acme example rob pike apparently had an elaborate answer as to why he wouldn't allow to change the colorschme

    2. Configuration knowledge is anti-knowledge -- learning how to conform to the inessential quirks of a system somebody else made up

      good take on configuration

    3. 1 reply 1 retweet 5 likes Reply 1 Retweet 1 Retweeted 1 Like 5 Liked 5 Direct message Omar Rizwan‏ @rsnous Feb 16 More Copy link to Tweet Embed Tweet Mute @rsnous Unmute @rsnous Block @rsnous Unblock @rsnous Report Tweet Add to other Moment Add to new Moment Replying to @rsnous @disquiet07 files are a weak lowest-common-denominator interface between programs in different languages (C, Python, Ruby, Swift, VB, bash, etc) in ecosystems with one language (iOS, JS, Lisp, Smalltalk), you often don't see files: you just persist the rich native structures of the language 4 replies 2 retweets 16 likes Reply 4 Retweet 2 Retweeted 2 Like 16 Liked 16 Direct message Gordon Brander‏ @gordonbrander 3h3 hours ago More Copy link to Tweet Embed Tweet Mute @gordonbrander Unmute @gordonbrander Block @gordonbrander Unblock @gordonbrander Report Tweet Add to other Moment Add to new Moment Replying to @rsnous @disquiet07 OTOH — lowest common denominator interfaces allow for emergent behavior. They focus all the constraints in one place, leaving the rest of the system definition open-ended. Like defining the LEGO dot, but not what shape pieces may take. 1 reply 0 retweets 3 likes Reply 1 Retweet Retweeted Like 3 Liked 3 Direct message Omar Rizwan‏ @rsnous 2h2 hours ago More Copy link to Tweet Embed Tweet Mute @rsnous Unmute @rsnous Block @rsnous Unblock @rsnous Report Tweet Add to other Moment Add to new Moment Replying to @gordonbrander @disquiet07 With files, imo the lack of structure 1. forces duplication of functions at the app level (de/serialization, cross-links, …) and 2. prevents coordination for higher-level behavior #1 here seems different from LEGO, but I can't quite articulate it in terms of your analogy 1 reply 0 retweets 2 likes Reply 1 Retweet Retweeted Like 2 Liked 2 Direct message Gordon Brander‏ @gordonbrander 2h2 hours ago Follow Follow @gordonbrander Following Following @gordonbrander Unfollow Unfollow @gordonbrander Blocked Blocked @gordonbrander Unblock Unblock @gordonbrander Pending Pending follow request from @gordonbrander Cancel Cancel your follow request to @gordonbrander More Copy link to Tweet Embed Tweet Mute @gordonbrander Unmute @gordonbrander Mute this conversation Unmute this conversation Block @gordonbrander Unblock @gordonbrander Report Tweet Add to other Moment Add to new Moment Replying to @rsnous @disquiet07 I agree. Low-level interop has a high floor, high ceiling. Higher-level interop (like Smalltalk) has lower floors, because deeper system integration. However, that deeper integration often means you end up more entangled with the system’s strengths and weaknesses.
    1. I am a grad student. I sought help for my mental illness last year. I go to one of those 'top 10' universities in the US. Grad life is hard, I do not have a lot of support from my family, and I am socially awkward. As far as coursework and work was concerned, I was struggling to organize my work and time. I used to be a huge fan of services like Trello, RescueTime, Evernote, all those technologies out there for managing and organizing. I used notepad or MS Word for documentation and writing reports. I wrote code in Visual Studio and Anaconda's Spyder (no offense to Anaconda). That's what my friends were doing, but I guess it was not enough for me, because I tend to get very nervous when there is a lot of work, and the smallest things can push me off the edge. I need everything to be organized and neat. I discovered Emacs in May 2018. I was in a terrible place then. I thought I was never going to recover. I was just trying out different text editors to optimize my workflow when I found Emacs. The first thing that completely amazed me was org-mode: agenda, the tree structure, org-babel, everything! Then I started writing all my code in Emacs, for all my coursework and work in machine learning, game development, etc. I learned how to store links to particular lines in huge code files, so that I can access them quickly, and continue work where I had left off. I also journal, I have been journaling for 4 years, that is how I deal with my problems. I have tried many software packages for journaling, and none of them come close to what I can do in Emacs. Now I can also write lisp scripts for doing simple routine processes that would make my workflow much simpler, so that I don't have to worry about small details and concentrate on more important things. I have recovered significantly from my depression. I still feel terrible, but I can handle things with more ease because Emacs reduces a lot of unnecessary cognitive load. I wonder what I would have been if I had decided not to explore Emacs. It's true what they say, any text editor can save your files, only Emacs can save your soul.

      about emacs helping to recover from depression, wow!

    1. Rob Pike has described Plan 9 as "an argument" for simplicity and clarity, while others have described it as "UNIX, only moreso."

      idea of a system as an argument pointed out by: https://twitter.com/rsnous/status/1054631468142493696

    1. TIL this is meant to work in Clojure and ClojureScript. Wow… cool! (keys (filter (comp pos? val) {:a 0, :b 1}))

      filter returns mapentries so not a map yet keys works on that!

    2. "Every person is born with an implicit short position on a stream of food and shelter for the length of their life."

      ?? we're making promises conditional on that supply?

    3. The CTO of @circleci aggregated data on build stability and grouped by language. Clojure is most stable, Swift is flakiest. Super interesting. #GitHubUniversepic.twitter.com/D8VEtVDHt8

      clojure stability is it just cause those langs break in runtime?

    4. But the real issue here is the implicit assertion that "improving beginner experience" and "improving expert powers" are in opposition to each other. This talking point is at least five years old, and has never been substantiated.

      ztellman

    5. 3) de-mangle function names (as C++ does) 4) print the stacktrace in a helpful order so I don't have to scroll up 100 lines to see the error 5) Hide implementation details like invokeStatic 6) Show code lines. Do all that and Clojure stack traces would get 100x better.

      tb

    6. What python does would be helpful here: 1) don't show more than one layer of internals. Show the clj.core method, but not the lang.RT methods. 2) implement guards to catch errors at the boundaries of user code instead of in the internals of Clojure <cont>

      tb

    1. function coll-of allows a :count key to specify the required number of elements:

      good to know that there is the keyword directive :count

    2. In computer science and logic, a dependent type is a type whose definition depends on a value. A "pair of integers" is a type. A "pair of integers where the second is greater than the first" is a dependent type because of the dependence on the value.

      this is not the most impressive defitnition but it does the job ;) it's more like "relational types" where type definitions include relations between potential values

    3. On the flip side, it can go further than mere types, including emulating dependent types and programming-by-contract.

      spec though it's used at runtime (not compile time)

      • hence: not a replacement for types as such BUT
      • enables dependent types
      • programming by contract
    1. Perhaps part of the confusion - and you say this in a different way in your little memo - is that the C/C++ folks see OO as a liberation from a world that has nothing resembling a first-class functions, while Lisp folks see OO as a prison since it limits their use of functions/objects to the style of (9.). In that case, the only way OO can be defended is in the same manner as any other game or discipline -- by arguing that by giving something up (e.g. the freedom to throw eggs at your neighbor's house) you gain something that you want (assurance that your neighbor won't put you in jail).

      [9] "Sum-of-product-of-function pattern - objects are (in effect) restricted to be functions that take as first argument a distinguished method key argument that is drawn from a finite set of simple names."

    2. Sum-of-product-of-function pattern - objects are (in effect) restricted to be functions that take as first argument a distinguished method key argument that is drawn from a finite set of simple names.

      fwiu: the "finte set of simple names" are all the objects defined in the codebase e.g. in java there are no functions as such just methods attached to classes i.e. "their key argument"

    3. All you can do is send a message (AYCDISAM) = Actors model - there is no direct manipulation of objects, only communication with (or invocation of) them. The presence of fields in Java violates this.

      from what I understand in Java... there are some variables on classes (class instances) that are only acessible through methods and for those the "only send message" paradigm holds but there are also fields which are like attributes in python which you can change directly

    4. Parametric polymorphism - functions and data structures that parameterize over arbitrary values (e.g. list of anything). ML and Lisp both have this. Java doesn't quite because of its non-Object types.

      generics so you've got a "template" collection e.g. Collectoin<animal> and you parametrise it with the Animal type in this example how is that broken by "non-Object types" in java</animal>

    5. Ad hoc polymorphism - functions and data structures with parameters that can take on values of many different types.

      does he mean that list in python is polymorphic because it can be list of integers or string or ... ?

    6. Encapsulation - the ability to syntactically hide the implementation of a type. E.g. in C or Pascal you always know whether something is a struct or an array, but in CLU and Java you can hide the difference.

      is this because:

      • interfaces--contextually identical (because satisfy common set of behaviours)?
      • or being wrapped in objects (thus blurring the difference)?
    1. Following Christopher Strachey,[2] parametric polymorphism may be contrasted with ad hoc polymorphism, in which a single polymorphic function can have a number of distinct and potentially heterogeneous implementations depending on the type of argument(s) to which it is applied. Thus, ad hoc polymorphism can generally only support a limited number of such distinct types, since a separate implementation has to be provided for each type.

      kind of like clojure multimethods but those can dispatch on arbitary function hence arbitrary "property"

    2. In programming languages and type theory, parametric polymorphism is a way to make a language more expressive, while still maintaining full static type-safety. Using parametric polymorphism, a function or a data type can be written generically so that it can handle values identically without depending on their type.[1] Such functions and data types are called generic functions and generic datatypes respectively and form the basis of generic programming.

      so essentially this is just a way to escape the contrains of types--overspecifying the type of argument for e.g. append function

      I guess the behaviour implement cannot really implement on the type of value

    1. One is the linked list of lines you mention. I believe this is intended to solve a display problem that TECO (the original language in which Emacs was implemented) had solved differently using the "gap" data structure. The fundamental issue was that if you have a buffer represented as a single block of contiguous text, then insertion on a character-by-character basis can be O(n2), each time you insert a character, you have to copy the entire subsequent buffer over one space.

      implementation, performence of text entry

    2. Lisp macros were also useful for the definition of new control structures, as well as new data structures. In ZWEI, we created a new iterative control structure called charmap, which iterates over characters in an interval. Intervals are stored as doubly-linked lists of arrays, and the starting point might be in the middle of one array and the ending point might be in the middle of another array. The code to perform this iteration was not trivial, and someone reading it might easily not understand the function it was performing, even though that function was the conceptually simple one of iterating over characters. So we created a macro called charmap that expands into the double-loop code to iterate over the characters. It is simple and obvious, and is used in many places, greatly reducing the size of the code and making the functionality obvious at a glance.

      use of macros implementing data structures making things more readable!

    3. It became policy to avoid abbreviations in most cases. In ZWEI, we made a list of several words that were used extremely often, and established 'official' abbreviations for them, and always used only those abbreviations. ... Words not on this list were always spelled out in full.

      abbreviations whitelist - good programming practice!

    4. The use of the mouse is still considered experimental. We know of several editors which depend highly on the use of a mouse for input, but we are not convinced that it is better than a keyboard; after more people start using ZWEI, it will be interesting to see how many of them make heavy use of the mouse and how many hardly use it at all.

      mouse considered experimental mouse better than keyboard?

    5. Since ZWEI is written in Lisp and lives in the Lisp environment of the Lisp machine, it is in a very good position to interface closely with other elements of that environment.

      living system interacting with a running lisp machine

    6. ZWEI is display-oriented: the text the user is editing is actually displayed (this is relevant because many editors of the time often showed out-of-date text due to efficiency and bandwidth restrictions, putting the burden on the user to imagine what their text looks like currently).

      bandwith restrictions -> out of date text -> user has to imagine what it currently looks like

    7. Some paragraphs are devoted to what must have been a novel concept at the time for such a system: that the Lisp Machine was a personal system, not time-shared, and this gave rise to features not viable on time-sharing systems, due to the fact that the user was not contending with other users for resources.

      personal computers as novel concept (vs time sharing) and what it enables

    1. (How it works: every time you access a document in Mosaic, the group annotation server [if you're using one] is queried with the URL of the document you're viewing; if any group annotations exist for that document, the group annotation server returns to Mosaic corresponding hyperlinks which are inlined into the document just like personal annotations. So the assumption is that you've got a fast local net and group annotation server host. In the Mosaic Annotate and Audio Annotate window there are option menus that let you select 'Personal' or 'Workgroup' each time you make an annotation; for the latter, Mosaic sends the annotation over a socket to the group annotation server.)

      Marc Andreesen about Mosaic anotations server