Programming thread

And don't you want to be able to finish half-assed class implementations at runtime by idiomatically redefining method_missing like a fucking degenerate, data security and encapsulation be damned?
Serious question (I know nothing about security): how is this exploitable? I mean, if you have access to memory enough to attach a new method to a class, why isn't it possible to read a class field from memory?
 
Serious question (I know nothing about security): how is this exploitable? I mean, if you have access to memory enough to attach a new method to a class, why isn't it possible to read a class field from memory?
It's not. The forced data encapsulation by hiding data in the internals of a class is basically language holding your hand to discourage bad practices in fucking with data structure's internals from outside.
 
@Marvin on the off chance you're using Windows, what are you using for OCaml? I happen to have an assignment in that language due in a couple days.

EDIT: It also happens to be about building a compiler with syntax trees and all that, like what was literally just discussed in this thread lol
 
Last edited:
This is basically how objects already work in JavaScript. God, I hate JavaScript.
Prototype oop systems can be a legitimately interesting, effective implementation of oop. But I feel that they're kinda like a neat party trick, at least not without some higher level syntax for them. They're a neat trick to show how simple of an oop system you can build upon a lower level language like the lambda calculus.

But you need higher level syntax so people aren't always messing with the prototype by hand. You can get really fucky code when you start confusing the object itself for the prototype.

With Javascript, they eventually introduced a proper class/extends syntax, but it was way too late. There's tons of code out there that messes with the prototype by hand, as well as lots of tutorials teaching naive, new programmers to keep on repeating the fuckup.
The most mind-fuckery book on Lisp I have read is "The Art of the Metaobject Protocol," which Alan Kay described as the best book on OOP in ten years. It's a book which ostensibly teaches the Common Lisp Object System. However, it expects you already to be pretty familiar with the Common Lisp Object System. This is not a mistake.
I love CLOS (or, well, I've only ever used scheme based knockoffs). I implemented a CLOS clone in scheme once. I didn't implement the whole metaobject protocol, which I agree, is some pretty crazy mind-fuckery. But I got basic classes+methods working. It was thoroughly satisfying when I finally started to be able to write more code in my CLOS-clone than basic scheme.
@Marvin on the off chance you're using Windows, what are you using for OCaml? I happen to have an assignment in that language due in a couple days.

EDIT: It also happens to be about building a compiler with syntax trees and all that, like what was literally just discussed in this thread lol
Alas, I am not on Windows. I'm on Linux.

Honestly? I usually like to have just a text editor like emacs open, with a few windows of what I'm working on, and a few terminals to run utop for testing the code.

I have a big text file called notes that just has like (obviously) notes, but also a bunch of utop commands I can paste into the terminal to get up-to-speed quickly. Like this:
Code:
#require "core_kernel";;

#require "lwt";;
#require "lwt_ppx";;
#require "lwt.unix";;

#require "logs";;
#require "logs.lwt";;

#require "ppx_deriving";;
#require "ppx_fields_conv";;
#require "ppx_sexp_conv";;
#require "sexplib.num";;
#require "ppx_let";;
#require "ppx_sexp_value";;

#mod_use "src/my_first_module.ml";;
#mod_use "src/my_second_module.ml";;
#mod_use "src/my_third_module.ml";;

(* etc *)
It's pretty much how I work on anything. The reason being, I hate being in a big complicated IDE and then having to figure out the difference between what commands the IDE is running and what I'd need to put in, say, a travis CI script or docker or whatever. I've had a few incidents where I spent like two hours trying to figure out why my code works in the IDE debugger but not when I actually build my docker image, and at that point I just threw my hands up and gave up on them entirely.

One time at work I was bored and I set up all the popular emacs plugins for Ocaml, and that wasn't too difficult, but in my day-to-day life I mostly just get by using the text editor and the REPL. (like I said, utop is a very nice one)

Also nice, compilers are very a natural fit for an ML language.
 
@Marvin on the off chance you're using Windows, what are you using for OCaml? I happen to have an assignment in that language due in a couple days.

EDIT: It also happens to be about building a compiler with syntax trees and all that, like what was literally just discussed in this thread lol
If you're on windows, why not just use F#?
edit q: @Marvin where would you suggest getting started with OCaml?
 
Alas, I am not on Windows. I'm on Linux.

Honestly? I usually like to have just a text editor like emacs open, with a few windows of what I'm working on, and a few terminals to run utop for testing the code.

I have a big text file called notes that just has like (obviously) notes, but also a bunch of utop commands I can paste into the terminal to get up-to-speed quickly. Like this:
Code:
#require "core_kernel";;

#require "lwt";;
#require "lwt_ppx";;
#require "lwt.unix";;

#require "logs";;
#require "logs.lwt";;

#require "ppx_deriving";;
#require "ppx_fields_conv";;
#require "ppx_sexp_conv";;
#require "sexplib.num";;
#require "ppx_let";;
#require "ppx_sexp_value";;

#mod_use "src/my_first_module.ml";;
#mod_use "src/my_second_module.ml";;
#mod_use "src/my_third_module.ml";;

(* etc *)
It's pretty much how I work on anything. The reason being, I hate being in a big complicated IDE and then having to figure out the difference between what commands the IDE is running and what I'd need to put in, say, a travis CI script or docker or whatever. I've had a few incidents where I spent like two hours trying to figure out why my code works in the IDE debugger but not when I actually build my docker image, and at that point I just threw my hands up and gave up on them entirely.

One time at work I was bored and I set up all the popular emacs plugins for Ocaml, and that wasn't too difficult, but in my day-to-day life I mostly just get by using the text editor and the REPL. (like I said, utop is a very nice one)

Also nice, compilers are very a natural fit for an ML language.
Yeah, I ended up downloading an Ubuntu VM and command-line interpreter like what the grader's supposed to use.
If you're on windows, why not just use F#?
It's a school assignment and it specifically says to use OCaml (and that it's going to be tested with an OCaml interpreter).
 
  • Winner
Reactions: Shoggoth
If you're on windows, why not just use F#?
edit q: @Marvin where would you suggest getting started with OCaml?
Real World Ocaml is the best programming book I have ever read. There's the original version, but they've been working on updating it to cover what aspects of the tooling and language have changed since the first version. I linked the in-development version, and the first version is here.

It's a really good programming book because it doesn't just cover theory, but it goes really in depth for practice as well.

For example, it doesn't just say "ignore memory, the garbage collector will handle it". Rather it says, "the garbage collector is tuned very well, but.., it's a tool and sometimes you need to adjust your tools, here's how you do it". It's very practical in that sense.

So there's a whole section on the runtime system, memory layout, garbage collector, the FFI, etc. (Now I almost never have to touch that stuff, but it's very nice to have it available. Plus it's an interesting read anyway.)
 
I have a big text file called notes that just has like (obviously) notes, but also a bunch of utop commands I can paste into the terminal to get up-to-speed quickly.
I shove these into ".ocamlinit" so they're automatically loaded by utop.

Code:
#require "lwt";;
#require "lwt_ppx";;
#require "lwt.unix";;
I took a break from Ocaml when I moved jobs, and have only come back to it recently for a personal project. I don't remember the combination of utop and lwt being so awesome. In fact, it just wasn't even slightly intuitive to me that it would be as good as it is, so I went and peeked into the utop code and saw that the REPL is implemented as lwts. And that, I assume, explains why I can run servers from utop and have them run asynchronously with the toplevel loop, without having to muck around with any synchronisation.

One time at work I was bored and I set up all the popular emacs plugins for Ocaml, and that wasn't too difficult, but in my day-to-day life I mostly just get by using the text editor and the REPL. (like I said, utop is a very nice one)
merlin was good before, but it's really good now, and it massively improves quality of life for me. It used to be able to tell you the type of identifiers in your code if you hit C-c C-t over them. Now you can highlight subexpressions and get it to tell you the type. And your code doesn't even have to compile for it to be able to do this. I can't get anything like this to work in Haskell.

Also, ocamlformat.
 
Can these be specified per repo or is there just a global ~/.ocamlinit?
The interpreter looks in the current working directory and then in $HOME if it can't find .ocamlinit. The behaviour is part of Ocaml proper (rather than utop specifically). From the Ocaml manual here:

"On start-up (before the first phrase is read), if the file .ocamlinit exists in the current directory, its contents are read as a sequence of OCaml phrases and executed as per the #use directive described in section 10.2. The evaluation outcode for each phrase are not displayed. If the current directory does not contain an .ocamlinit file, but the user’s home directory (environment variable HOME) does, the latter is read and executed as described below."

I just put mine in the root directory of each repo.
 
  • Informative
Reactions: Marvin
Serious question (I know nothing about security): how is this exploitable? I mean, if you have access to memory enough to attach a new method to a class, why isn't it possible to read a class field from memory?
It's not. The forced data encapsulation by hiding data in the internals of a class is basically language holding your hand to discourage bad practices in fucking with data structure's internals from outside.
Yeah @DidYouJustSayThat's right. My example with the bank_info() variable was tongue-in-cheek, since you'd never just rely on class data-hiding to protect actually sensitive data. The main idea behind private/protected/etc data-hiding is to signal to other programmers that use your class that they shouldn't be messing with those variables/functions since they'll probably break the code in some subtle yet easily-avoidable way.

That said, part of my point was mainly how gross it feels to be redefining important error-handling code like method_missing for such a purpose. The added fact that some Rubyists laud this as a design pattern on par with the famous patterns of the GangOfFour kind of makes my skin crawl:
whywouldtheydothis.png
 
Yeah @DidYouJustSayThat's right. My example with the bank_info() variable was tongue-in-cheek, since you'd never just rely on class data-hiding to protect actually sensitive data. The main idea behind private/protected/etc data-hiding is to signal to other programmers that use your class that they shouldn't be messing with those variables/functions since they'll probably break the code in some subtle yet easily-avoidable way.

That said, part of my point was mainly how gross it feels to be redefining important error-handling code like method_missing for such a purpose. The added fact that some Rubyists laud this as a design pattern on par with the famous patterns of the GangOfFour kind of makes my skin crawl:
I came from Java to Python, and there's a lot of this in Python libraries. The worst thing for me is it breaks IDEs. "What's the source code for that method? Haha get fucked, even the name is generated at runtime."
 
Funny thing about this thread: I think the link to n-gate was posted somewhere here, and its author is routinely mocking Rust Evangelists Force. It made me a bit biased towards Rust, until I started researching memory safety.
 
  • Informative
Reactions: Yotsubaaa
Funny thing about this thread: I think the link to n-gate was posted somewhere here, and its author is routinely mocking Rust Evangelists Force. It made me a bit biased towards Rust, until I started researching memory safety.
That was @moocow's post in the open source software community thread (which I'm starting to confuse with this one too, so you're not alone there, friend!)

Anyway, I actually did some Kiwi Farms relevant programming just now and wanted to share/inspire!

The situation: We've got a cow over in Proving Grounds who infamously blogs everything he does on his WordPress blog. But we, along with the community on 4chan that follow him, have started to notice that he's modifying his old blog posts to get rid of things that he later decides are incriminating (and sometimes literally so). We've got most everything archived so it's not too big of a deal, but manually going through each of his blog posts and checking whether the post has been modified is a daunting task that requires more time and autism than any of us are willing to dedicate to the task.

The solution: Write a script to parse through his WordPress blog's sitemap, and order all of his blog posts by date last modified! If any of the older blog posts are suddenly moved to the top of the list, then we know to check those ones to see what he's changed.

So here it is (on a side note, where did the Kiwi Farms git repos go, guys?). It's quick, it's dirty, it's Ruby, but it does the job. I'm sure all of you guys could probably do it better than I did in your favorite languages, so let this motivate you!
Ruby:
#!/usr/bin/ruby

# A quick and dirty Ruby script. Given a WordPress blog, the script
# scans each of the pages listed in the sitemap and orders them
# according to most recent modification time.
#
# (i.e. Run the script and check the top blog posts! If older blog
# posts appear near the top of the list, then someone's been busy
# deleting/changing stuff.)

require 'nokogiri'
require 'open-uri'

# Assume blog post provided as command line args
if ARGV.length < 1
  raise(ArgumentError, "Blog URL not specified in command line args")
else
  base_url = ARGV.join("")
end

# Read in the blog sitemap XML to get the full list of blog posts
# and last modification timestamps
#TODO: Might be tricky if it's not in the usual place! Look into this?
SITEMAP = "/sitemap.xml"
URL_NODE_XPATH = "//url"
URL_TEXT_XPATH = "./loc"
LASTMOD_XPATH = "./lastmod"

sitemap_xml = Nokogiri::XML(open(base_url + SITEMAP))
sitemap_xml.remove_namespaces!

# Collect all the blog posts and their last modification times
lastmod_times = Hash.new
sitepages = sitemap_xml.xpath(URL_NODE_XPATH)
sitepages.each do |url_node|
  url_text = url_node.xpath(URL_TEXT_XPATH).text
  timestamp = url_node.xpath(LASTMOD_XPATH).text
  lastmod_times[url_text] = timestamp
end

# Sort by descending order of timestamp from most recent
lastmod_times = lastmod_times.sort_by {|url, time| time}.reverse.to_h

# Print to STDOUT and done! (Probably useful to pipe the output
# of this script into a file or grep or something.)
lastmod_times.each do |url, time|
  puts "Last modified #{time}: #{url}"
end

Usage example: Here's the five most recently modified pages for some dead Lisp blog I found with a quick google search:
usage_example.png
 
Last edited:
Funny thing about this thread: I think the link to n-gate was posted somewhere here, and its author is routinely mocking Rust Evangelists Force. It made me a bit biased towards Rust, until I started researching memory safety.
In fairness to Rust, I think n-gate's author is more taking the piss out of its "excessively enthusiastic" advocates more than the language itself.

<bait>Though everyone knows all real programmers use C. Memory safety is for babbies.</bait> :D
 
Here's some Emacs:

Code:
(require 'request)

(defun find-by-car (sym tree)
  (cl-loop with agenda = (list tree)
           while (consp agenda)
           for next = (pop agenda)
           if (and (consp next) (eq (car next) sym)) collect next
           else
             if (consp next)
             do (push (cdr next) agenda) (push (car next) agenda)))

(defun url-info (url-xml)
  `(url     ,(caddar (find-by-car 'loc url-xml))
    lastmod ,(caddar (find-by-car 'lastmod url-xml))))

(defun post-info (xml)
  (let ((url-xmls (find-by-car 'url xml)))
    (mapcar 'url-info url-xmls)))

(request
 "https://lispy.wordpress.com/sitemap.xml"
 :parser (lambda ()
           (let ((last-mods
                  (post-info
                   (libxml-parse-xml-region (point) (point-max)))))
             (setf last-mods (cl-sort last-mods 'string-greaterp
                                      :key (lambda (x) (plist-get x 'lastmod))))
             (dolist (elt last-mods)
               (message "Last modified %s: %s"
                        (plist-get elt 'lastmod)
                        (plist-get elt 'url))))))
I assume neither of us are parsing the time stamps and comparing the actual times?
 
Some Clojure
Code:
(require 'clojure.xml)
(defn sort-sitemap-by-lastmod
  [uri]
  (sort-by
   #(get-in % [:lastmod 0 :content 0])
   (map
    (fn [c]
      (update-in
       (group-by :tag (:content c))
       [:lastmod 0 :content 0]
       clojure.instant/read-instant-timestamp))
    (:content (clojure.xml/parse uri)))))
 
  • Winner
Reactions: Yotsubaaa
Here's some Emacs:
<snip>
I assume neither of us are parsing the time stamps and comparing the actual times?
Gorgeous! :)

And yeah, I haven't bothered doing any extra parsing or anything yet. (Although maybe that should be done: it occurred to me as I was checking the output timestamps for the blog that someone making a comment probably also changes the sitemap's last modification time too, maybe, which we're not so interested in. I'll have to check that.)

Some Clojure
<snip>
Beautiful. Fogus and Houser were right on the money, huh?
clojureftw.png
 
Gorgeous! :)
Nah, it's pretty ugly, and Elisp is not my choice of language for writing elegant code. But it was a solution that ran in my text editor.

The clojure looks much nicer, but it doesn't work for me with the example url.

I'm not sure what the most elegant solution for doing this sort of XML parsing is. There's a cute command line tool for querying and transforming JSON called "jq", and I'd like to imagine something like that for XML. Typed functional languages have various stories on parsing this sort of semi-structured data, but which one you choose is down to how much you trust your data to match schema.

The bottom line is that JSON, XML and YAML and all the other shit we're doomed to reinvent were really stupid ideas for representing semi-structured data, a problem that was solved back in the 50s with s-expressions with a solution that has yet to be surpassed.
 
Back