Sign in

Vladimir Keleshev

@keleshev.com
806 followers 438 following 57 posts

OCaml programmer, author of Compiling to Assembly from Scratch: keleshev.com/cas Copenhagen

PostsRepliesMedia
Vladimir Keleshev @keleshev.com · 18/08/2025
He was no Rafael, but look at this piece, could have been a banger punk rock cover!
Onfim’s drawing of two people
020 0
Vladimir Keleshev @keleshev.com · 15/05/2025
Onfim was not the greatest artist, but why do you have to rub it in like that?!
A probable self portrait by Rafael, drawn when he was around the same age (1499), Ashmolean Museum, Oxford, UK.
120 0
Vladimir Keleshev @keleshev.com · 03/05/2025
Like, what language is this?
@dataclass
class Parser[T]:
    parse: Callable[[Source], ParseResult[T] | None]

    @staticmethod
    def regexp(regexp: Pattern) -> Parser[str]:
        return Parser(lambda source: source.match(regexp))

    @staticmethod
    def constant[U](value: U) -> Parser[U]:
        return Parser(lambda source: ParseResult(value, source))
010 0
Vladimir Keleshev @keleshev.com · 02/05/2025
Glad to see that Python finally got more dedicated syntax for type annotations in 3.12. Now it looks quite decent. So I updated the Python version of the book's compiler to use the new syntax: github.com/keleshev/com...
@dataclass
class Parser[T]:
    _parse: Callable[[Source], ParseResult[T] | None]

    def parse(self, s: Source) -> ParseResult[T] | None:
        return self.__dict__['_parse'](s)
    
    @staticmethod
    def regexp(regexp: Pattern) -> Parser[str]:
        return Parser(lambda source: source.match(regexp))

    @staticmethod
    def constant[U](value: U) -> Parser[U]:
        return Parser(lambda source: ParseResult(value, source))
230 0
Vladimir Keleshev @keleshev.com · 22/12/2024
I got two Pi 400 originally as Minecraft devices for kids on Christmas, but since then they are not using it much for Minecraft, more for Math Academy and school stuff. We got Nintendo Switch since then, so most gaming moved there.
Two Raspberry Pi 400 wrapped in Minecraft gift paper.
110 0
Vladimir Keleshev @keleshev.com · 20/11/2024
Excellent! Now use fold. gist.github.com/keleshev/36e...
  let size = fold ~leaf:(const 1) ~node:(+)
  let height = fold ~leaf:(const 1) ~node:(fun l r -> 1 + max l r)
  let to_string leaf = fold ~leaf ~node:(sprintf "(%s %s)")
  let reverse = fold ~leaf ~node:(fun l r -> node r l)
  let map f = fold ~leaf:(f >> leaf) ~node
  let bind f = fold ~leaf:f ~node
  let iter f = fold ~leaf:f ~node:(fun _ _ -> ())
  let for_all predicate = fold ~leaf:predicate ~node:(&&)
  let exists predicate = fold ~leaf:predicate ~node:(||)
2120 0
Vladimir Keleshev @keleshev.com · 01/11/2024
The grammar. The parser. I love doing this.
    # Recursive definition of pattern
    required <- "(" _ pattern ")" _
    optional <- "[" _ pattern "]" _
    confined <- required / optional / atom _
    multiple <- confined ("..." _)?
    sequence <- multiple multiple*
    junction <- sequence ("|" _ sequence)*
    pattern <- junction  let rec pattern x =
    let required = token "(" %> pattern <% token ")" in
    let optional =
      let+ pattern = token "[" %> pattern <% token "]" in
      Pattern.Optional pattern in
    let confined = required / optional / atom in
    let multiple =
      let+ pattern, ellipsis = confined <%> maybe (token "...") in
      if ellipsis = None then pattern else Pattern.Multiple pattern in
    let sequence =
      let+ first, rest = multiple <%> zero_or_more multiple in
      List.fold_left Pattern.sequence first rest in
    let junction =
      let+ first, rest = sequence <%> zero_or_more (token "|" %> sequence) in
      List.fold_left Pattern.junction first rest in
    junction x
120 0