/dpt/ - Daily Programming Thread

Pure Functional Programming Edition


What are you working on, Sup Forums?


Previous Thread:

Other urls found in this thread:

en.wikibooks.org/wiki/Haskell
godbolt.org
hastebin.com/awozojufaz.php
pelulamu.net/ibniz/
twitter.com/SFWRedditGifs

Reiterating question:

How difficult would it likely be to write a custom Desktop Environment for BSD?

And what libraries would I need to use? Assume I want to primarily write it in C++ with OpenGL.

Can it be written as standalone, so that its only interaction with the Shell would be through passed Shell commands, and it just overlays itself over everything else (so, theoretically, you could close the DE, and you're left with the CLI behind it)?

Such as, double-clicking an icon on the desktop sends cd [whatever the directory is] and receives ls -a and you know, like then prints it to the screen and stuff?

In other words, not based on the X-Window System, but purely its own application?

In general, I guess my real question is: how would I go about writing a graphical application that can handle physical screens, and that is NOT a derived piece of software, but its own program reliant on nothing but its own libraries - functionally, its own API?

How much would I need to personally fuck with drivers? Assume a driver exists for, idk... an AMD Sapphire graphics card.
So, I have the driver, I have all the standard UNIX C libraries, I have 3 monitors, OpenGL, and I have a lot of time.
Is there anything else I'd need, or is that pretty much it, just look at the return values for the GPU, and use them to define things like screen size and rotation for the DE?

How do I make my own programming language and virtual machine like Python?

Haskell is really good for writing programming languages in

Start by defining the structure of your program, expressions, declarations, syntax etc

A simple example:

data Expr =
Var String
App Expr Expr
Abs String Expr
-- e :
-- x
-- e e
-- \x.e


data Declaration = Declare String Expr
-- x = e

You write a program that parses entered text based on a custom syntax and does things with it.

Usually, you will write the parser in C/++.

So, in other words, you write a C/++ program that looks through the crap you input, finds where it expects things to be, returns errors if the syntax is wrong, and does other things if it's right

Where could I learn to do this (grammar -> haskell)?

Whoops, forgot |-s
should be
Var String
| App Expr Expr
| Abs String Expr

Holy fuck, someone in my Discord showed me Haskell code. It's fucking ridiculous.

What autism is required to learn this language, seriously? And, I'm a sperg, too, so I should know.

en.wikibooks.org/wiki/Haskell

depends on how hardcore you want to go
easiest route would be to simply use a graphics library like SFML or SDL, make a fullscreen window and then just draw on it
this requires no driver code or any other libraries besides a text library and an audio library if you want to have clicking sounds and whatnot

godbolt.org

this is neat

Python is weird. Closures are late-binding but default args are immediate.

What if I want to write the VM first then put my language on top

pls link to resources explaining how stuff works in detail

SFML and SDL would make it an Xorg client.
user's wants to make a non Xorg display server

It's really easy to write an interpreter to begin with

reposting from old thread:

I know I am going to sound like a dickhead for suggesting something else, but have a look at Wayland.

Wayland itself is just a way for a client to talk to a compositor and vice versa.

you can get really low level with it, like writing individual pixels on the screen without using anything like OpenGL

Also, your compositor (WM) will be able to support other Wayland clients

example of untyped lambda calculus in haskell
uses de brujin indices so it'd be a pain to write in

And here's a much much simpler one, without a REPL or parsing, and without capture avoiding semantics (it uses naive substitution).

Go on

Working on akari-bbs!

Index mode should be working now.
The old version was 3 times more verbose and randomly froze.
Next up is getting the pager to grow with the actual thread count on the current board.

One second, I'll write an extremely simple example

>He still programs
>In current year

You might do a search for "make a lisp".

It's a github project aimed at people learning how to create interpreters.

Once you're comfortable with that, learn about how VMs work and the different models.

It's graduate level stuff, though, FYI.

>graduate level
>third semester at my uni
huh

actually found this from earlier
it just does stack operations

if you look all the way at the bottom, there's a do block in the embedded language


Probably this file from a school project we made for Android. Its a match-three game, the GameSession_update() function is the main loop. 4 different people worked on it. Its just full of magic numbers, non-sensical decisions and general idiocy.
hastebin.com/awozojufaz.php

What uni do you go to that has you designing and writing your own stack/register machines in 3rd year?

Assuming here you're not talking about simple MIX-style training VMs.

in this case runComp would be the interpreter

obviously you'd want something much more complicated, and probably a flat structure

H-huh? I dont understand Haskell... Last time I tried to learn language I ended up mindfucked by maths shit like categories or something

I can understand how main and the stack work tho

Bookmarked. I may take a look, but I really don't know why anyone would WANT to write like that.
C/++ is way nicer

I had considered SDL, since I have some limited experience with it. But, will this work for multiple monitors automatically?
Does SDL have a way to detect how many monitors there are and define the window blitting locations based on the coordinates? Like, say, 2 monitors are above each other, and you want the screens to act as if the top one is slightly further off to the left?

I'm talking like REAL hardcore. That's kinda why I was thinking of using OpenGL.

I actually meant the DE to INCLUDE a custom Window Manager.

In other words, without installing KDE, Xorg, Gnome, whatever, it should do the following, as base:
>know how many monitors there are
>know what resolutions I can put on each
>blit a full-screen image to every monitor (which becomes the easy part, just drawing all the icons, taskbars, crap like that)

So... maybe I worded it wrong. What, in general would I need to do with Drivers to receive the physical characteristics of monitors to create the Screen Objects?
>Drawing it is the easy part (if extremely long). I can probably do that without an issue.

(last thread)
Hmmm, so, can you explain exactly what it is that the programs will do?
Lemme use an example: Firefox or Chrome
Does FF or Chrome actually make calls to an existing WM or something, or does it just request screen space?

Err, not designing, just implementing. Same goes for the language, was pretty simple but had some cool features.

>C/++ is way nicer
This has got to be bait

(me)
The course was mostly on formal grammars and parsing, btw

>So... maybe I worded it wrong. What, in general would I need to do with Drivers to receive the physical characteristics of monitors to create the Screen Objects?

linux kms/drm

just so you know, your DE wont be compatible with any other applications

Keep up the good work user

Hey I'm interested in learning how to do this as well but in Linux.

It seems in Linux one can create an OpenGL ES context with no dependencies on X.

Heh...

Ok, that's a valid reason not to do it that way, then...
So, if I want to retain compatibility, I'd want to use Xorg as a basis?

Basically, take Xorg, and make my DE make calls to that, then?

Yeah, the point is just that we define an ADT called Computation that represents our mini language.
The only parts you should care about are:
>Instruction
>runComp
>main

There's the stuff about Free and liftF, you don't need to worry about.
In fact you can rewrite it like this, without using Free

>Does FF or Chrome actually make calls to an existing WM or something, or does it just request screen space?

Firefox doesn't interface with X directly, it uses libraries to do all that. Generally speaking, it uses GTK.

GTK has a modular structure, and uses the backend appropriate to deal with whatever windowing system it finds itself in. GDK, for instance, handles drawing.

You'd have to write your own backends for GTK to make firefox work. These backends would have to handle not only all display-related commands but also things like font handling, keyboard input, etc.

A good start there would be to look at the Wayland port of GTK. GTK was originally written for X, so the Wayland port should highlight the parts that you'd have to change to make it work with your API.

Like I said before, it's a huge task.

Ah, yes, that makes more sense.

I was assuming the guy I was replying to wanted to design his own.

>I'd want to use Xorg as a basis?
if you want maximum compatibility

but seriously, Wayland is much more low-level and is probably what you are looking for. It provides a way for compatibility with all clients no matter how you program your DE as long as you use the protocol correctly. It is difficult to understand how Wayland works at first however.

But how do you design a language and a VM instruction set?

It's important to get this shit right because I don't wanna fuck it up and have to break compatibility with my own programs later.

I already understand a lot of concepts but what I don't know is whether to do a register or stack-based VM, how to design the instruction set, do I make them instructions polymorphic or not, how do I encode instructions and why, this kind of shit

I've written a toy gameboy emulator before and its essentially a VM for the system but then I had a real, already designed system to model, now I wanna come up with my own and I am paralyzed by the freedom

>uses de brujin indices so it'd be a pain to write in
That's what polymorphic recursion is for. Capture-avoiding solution forms a monad.
data Term a
= Var a
| Lam (Term (Maybe a))
| App (Term a) (Term a)
deriving Functor

instance Monad Term where
return = Var
Var a >>= k = k a
Lam body >>= k = Lam (body >>= sequence k)
App fun arg >>= k = App (fun >>= k) (arg >>= k)


This isn't the only way to formulate it, but it's solid. You can experiment with changing abstraction to this:
Lam (Maybe (Term (Maybe a)))

which is a kind of encoding of explicit substitutions but because of laziness I'm not sure it actually makes a difference.

>A good start there would be to look at the Wayland port of GTK. GTK was originally written for X, so the Wayland port should highlight the parts that you'd have to change to make it work with your API.

>if you want maximum compatibility
>but seriously, Wayland is much more low-level and is probably what you are looking for. It provides a way for compatibility with all clients no matter how you program your DE as long as you use the protocol correctly.

Hmmm, I'll look into that, then.

So, Wayland Port of GTK. I'll try to find it, and start looking at it.

Thanks

Er, sorry, that's not right, should be:
Lam (Term (Maybe (Term a)))

So if you look at the n in the instructions, that actually corresponds to a kind of continuation - the remainder of the computation to perform.
e.g.
Push x n
means
push x onto the stack, then do n
e.g.
Push x (Push y (Push z (return ())))
>push x then push y then push z then return unit (analagous to void return;)

return/pure does nothing, it just allows you to insert a regular value into your monad

In the case of Pop, you have a function that expects the item from the stack
Pop (\x -> .. do something with x)
e.g.
Pop (\x -> Pop (\y -> Push (x + y) (return ()) ))
>x = pop()
>y = pop()
>push(x + y);
>return

or in do notation

>do
>x y push (x + y)
>return ()

>that
>extremely simple to someone who doesn't know Haskell

Ah, this makes sense suddenly
Maybe a is a + 1
So I take it you're doing
Term (Term (Term (Term ... ) ) )
?

I'll rewrite something better, but the only parts you should be reading are
Instruction
runComp
main

Speaking of continuations, how the hell are they implemented? I just don't see how

Scheme's default continuations are actually bullshit and extremely hard to explain and understand, someone generalized it into delimited continuations that allows you to "mark the stack" at any point; scheme's traditional continuation being a delimited one that goes all the way to the bottom of the stack. Much easier to understand, but still no idea how to implement that shit


Also please take a look at

The type parameter is the set of free variables. A closed term is forall a. Term a or Term Empty, same thing.

In the simpler formulation you only have Term (Term a) if you map a substitution instead of binding for some reason. Like I said, it's a regular monad.

Fixpoints of functors (like free monads) are a different thing altogether.

Honestly, man, you're biting off way more than any one person can chew. The fact that you're asking these questions tells me that you're greatly underestimating the amount of work involved.

Figure out what part of the problem interests you most, then work on that using existing software. If it's window management you're interested in, write a window manager for X. If it's low-level graphics you're interested in, learn how to work with the framebuffer console and make screensavers or something.

You know the phrase gotta learn to walk before you can run? In this case, you need to learn to build the floor first.

He's talking about delimited continuations here, which are really just closures. You typically call the function argument of monadic bind a continuation because it's "the rest" of the computation.

Full continuations are kinda wacky.

Not him but I want to deal with something similar: an application that runs directly on top of the Linux kernel and can somehow output graphics and sound and work with input devices. I just want to attain a simple understanding of all this stuff without all these toolkits and libraries in the middle. I want the program to be the toolkit.

Right now I know how to use Linux's system calls and libevdev but I'm kinda stumped on the audiovisual systems.

>Honestly, man, you're biting off way more than any one person can chew. The fact that you're asking these questions tells me that you're greatly underestimating the amount of work involved.
I'm not intending this to be a thing for one person.

I'll be launching a few things, and part of the funding from them after they're up and running will be going towards a full UNIX OS development project.
I intend to have several hundred people working on this, and I'm well-prepared for it to be a few tens of GB. I would want to have a general idea before I get started, though, because I plan to at least be involved in several of the sub-phases, because I actually like to program, and want to have a bit of fun with it.

But, to be fair, maybe I don't have the /Business Rules/ well thought-out, yet...

How about this:
>If I want a system that does NOT use a system-specific API to run programs, what is the best way to go about this?
Or... maybe even...
>What is the best way to create an API that will run anything, with no specific display elements that can't be called somewhere else?
In other words:
Window* win = new Window();

to work on my machine, as well as something running Linux, BSD, Solaris, or OSX?
In other words, what is the best way to make a purely platform-/distro- agnostic display system?
If X will allow me to do that, I suppose there's no issue using it as the base and just building from there. If Wayland will allow me to do that, that'd be good to.

So, when someone calls a new window from OpenGL, SDL, SFML, Qt, whatever, I just want it to pass to the DE and create a generic "window", which is then handled by the DE, through calls to the hardware and such. When it saves, idk, game progress, it should only have to send the DE a POSIX command, which the DE passes down to the Shell.

You know?

This is why I was originally interested in the idea of NOT using X or anything.

Ok, here
module Main where

import Control.Monad.State (modify, execState)

data Instruction = Pop | Push | Swap | Add | Count
-- the various instruction types
data MachineState = Mac Int Int [Int]
-- the first int is register0
-- the second int is register1
-- the [Int] is the stack, a list of ints
type Program = [Instruction]
-- A program is a list of instructions

execute Pop (Mac r0 r1 stack) = Mac (head stack) r1 (tail stack)
execute Push (Mac r0 r1 stack) = Mac r0 r1 (r0 : stack)
execute Swap (Mac r0 r1 stack) = Mac r1 r0 stack
execute Add (Mac r0 r1 stack) = Mac (r0 + r1) r1 stack
execute Count (Mac r0 r1 stack) = Mac (length stack) r1 stack

program = [Pop, Swap, Pop, Add, Swap, Count, Add]
-- pop a value, swap it into the second register
-- pop another value, add the two popped values
-- swap the result into the second register
-- get the number of items left in the stack
-- add it to the previous total
-- result: [x,y,...] -> x + y + (length of remaining stack)

run :: Program -> MachineState -> MachineState
run = execState . mapM_ (modify . execute)

main = print (run program (Mac 0 0 [3, 6, 8, 3, 4]))
-- 3 + 6 + (length of remaining stack - 3)
-- 12

instance Show MachineState where
show (Mac r0 r1 st) = unlines [
"Register 0\t" ++ show r0 ,
"Register 1\t" ++ show r1 ,
" Stack\t" ++ show st ]


Mostly comments and annotations.

In this case it's extremely easy to read, too.
In fact you could literally just add
deriving (Read)
to Instruction,


then a simple call to readLn and the user can input
"[Pop, Push, Swap, Add]" and Haskell will parse it for you

>its even worse now

How is that worse?

Look:
data Instruction = Pop | Push | Swap | Add | Count
I assume you can understand this?
It's just an enum.

data MachineState = Mac Int Int [Int]
this is like
struct MachineState { int r0, r1; list stack; }
but without names for the fields

execute Pop (Mac r0 r1 stack) = Mac (head stack) r1 (tail stack)
execute, when given the instruction "Pop", and a machine state (Mac r0 r1 stack), will return
Mac (head stack) r1 (tail stack)
Head is the head of the stack, i.e. the top item
Tail is the rest of it

what's the fewest number of characters you can use to make an interpreter for a turing complete language?

run = execState . mapM_ (modify . execute)
might be a bit awkward, but it's basically just this:

run (initialState, program)
state = initialState
foreach instruction in program
state = execute(instruction, state);
return state

Can't help you with the specifics, I'm afraid. I've never messed around with Linux's audio system.

Ah, I misread your intentions.

What you're suggesting sounds a lot like the wxWindows project. Have you check them out? I've used wxWindows for a project, and the end result ran on both Windows and Linux machines (and should theoretically run on anything with notification icons).

You have to compile for each platform, of course, unless the application is interpreted, but it's a great cross-platform system. It might be a good starting point for your universal desktop environment.

Ok, I'll take a look at that one. Thanks.

I don't think they are "late binding". Just that, you need to probably store a copy of n in a new variable and then use that in the variable.

i made a new thing using code i wrote in an older thread. scans a board and runs every post thru a sentiment analysis to find the most positive and negative posts. not super accurate of course

So, what would happen if I wrote this:
Go suck a pile of fat dicks, you disgusting homosexual faggot bitch? LOL XD XD

How would it rate me? I'm curious

reddit/10

What color scheme is that?

one dark

I just set up my own php server
this is so cool

Sentiment(polarity=-0.09999999999999998, subjectivity=0.85)

i think TextBlob is pretty bad desu, it just looks for words like "bad", "fuck", "terrible", "disgusting" etc. i dunno what a better library would be, though

Can a Chrome/Chromium user in this thread copy-paste the following code in their console and give me the output? I think I found a bug in firefox and am wondering how Chrome behaves before reporting it.
let a = {x: y}
let a = {"x": "y"}
a = {"x": "y"}
console.log(a)

Yeah, you want to look into DRM/KMS. That will give you control of the screens.
Then you can use GBM and EGL, and you can get an OpenGL (ES) context for that screen, and then you can draw shit using that.
Using libinput, you can get keyboard/mouse events.
For audio, I suppose you would just use ALSA.

Doing this all is actually pretty complicated.
I've done some of this stuff myself, for some testing code, but I only got to an OpenGL "hello triangle" on the screen, with some pretty bad flickering. I was trying to get atomic page flipping working, but never got around to finishing it.

Heh, yeah, you'd need to look at context too.

I'm not really sure off the top of my head how you'd go about that.

But, yeah.
Although, what does subjectivity refer to in that?

I'm curious

i can't really exactly tell. from what I can say though, it seems to just keep a database of words it deems to be more subjective, like "great" being 80% subjective (giving it a value of 0.8) or "very" only being 30% (0.3) subjective.

what's interesting is that polarity (positive to negative) is measure in 1.0 to -1.0, instead of 1.0 to 0.0 like subjectivity

Hmmm

Interesting

Yeah I had no idea how to do sound, I'll look into ALSA. It's the kernel interface correct?

I remember there used to be a lot of drama surrounding Linux audio, basically competition between ALSA, PulseAudio, JACK and god know what else. I have no idea what was the "conclusion" though

Doing graphics and input separately feels funny. I'm so used to having input be associated with "windows" that it's just weird to read input separately

I love this low level shit, I get to learn about all kinds of stuff that libraries usually abstract away.

This project really inspired me:

pelulamu.net/ibniz/

Imagine that, but interfacing with the kernel as directly as possible

>It's the kernel interface correct?
Yes, ALSA is the actual in-kernel audio system. It also refers to the userspace library, libalsa, for using that audio system.
>I'm so used to having input be associated with "windows" that it's just weird to read input separately
Yeah, at this level, you're reading straight from the files in /dev/input.
>stuff that libraries usually abstract away
Even at this level, if you want to keep your sanity and actually get anything done, you're going to need to use a few libraries.
Some of the libraries, like libdrm are provided by the kernel itself, so if you didn't do that, you would just needlessly be calling ioctls directly yourself.
Same with ALSA.
libgbm and EGL are a part of mesa. There isn't really any way to get around this if you want hardware acceleration and anything that is even slightly portable across GPUs.
libinput is just a necessity, unless you want to enumerate and use hundreds of different peripherals yourself, and manage all of the different quirks they have.

I'm fine with using those libraries.

>I have no idea what was the "conclusion" though

The conclusion: Linus fucked us all.

Not trolling, I'm serious. The #1 reason why Linux audio sucks so bad is because Linus refuses to put a software mixer in the kernel.

Yes, there are security issues, but those could be addressed.

So what we've got is ALSA, which may or may not support mixing depending on your hardware, with PulseAudio on top of that (which gives so many people problems and doesn't address any of the security issues), with your desktop environment's audio system on top of that. Then JACK on the side, fighting with PulseAudio for the sound device.

There's a lot of history behind all of this (read up on why Linux dropped OSS), and some points are debatable, but Linux's audio system is basically CONFIRMED WONTFIX.

Oh, and all of that is Linux-only. If you want audio on any other UNIX, you start again at the bottom.

It sucks, but that's the reality we have.

>The #1 reason why Linux audio sucks so bad is because Linus refuses to put a software mixer in the kernel.

Yeah that's kinda what I remember, your program would grab the sound card and if another one did the same it'd replace/override/fuck your audio

Seems perfect for my program though, which is going to have the machine all to itself anyway. I'll do mixing from within. As long as some other random process doesn't fuck me I suppose I'll be fine.

>Yes, there are security issues

What security issues?

What about real time audio? Sounds like that's pretty important for programs like ardour. I don't think desktop pulse audio supports that shit

Programs that need low latency audio would typically use JACK.

The sound card is a hardware device with I/O. Any time you have a single resource and multiple users, you have security issues.

To have a system-wide software mixer, who controls the mixer? Can User A mute the sound coming from User B's application? Can User B read from the microphone from a cron job while User A is talking to his doctor/lawyer/mistress/whatever?

There's no good answer for these, and nothing from the traditional UNIX world (at least in my experience - it's been a while). There should be an answer to these, but Linux distributions sidestepped everything by adopting PulseAudio which is user-specific.

I'd like to see something that can address these issues at the kernel/libalsa level, but I don't think it'll ever happen. Filesystems solve all these problems, why can't the audio system?

How does Apple's CoreAudio do it? Seems to be the most sophisticated API out there

Why aren't programs statically recompiled on install rather than directly compile to machine code or use a vm?

Programs would be compiled to bytecode like vm languages but you don't get the performance penalty.

Id say you could get even more performance because you can optimize the code for the specific chip you're running on even if they have the same architecture.

I'm studying some dataset to support police data driven decisions
pic related

And they said my Perl code is illegible.

No idea, I'm not a Mac guy.

Note that I don't actually work with this stuff; I've just been around a long time and paid attention when all this shit was going down. I'm one of the people that had really bad issues with Pulse in the early days, and followed a lot of the mailing lists at the time.

Nobody cares enough to do it, and any advantages would be extremely minimal.
Not to mention that it would require a massive overhaul of the compilation and linking system we have today.

If you really care about that stuff, install gentoo.
No, really.

Why is GHC's output such garbage?

Most of the time it doesn't matter enough to bother with.

In the cases where it does, oftentimes several versions of a critical function are included, and the program detects what CPU features are available and picks the function that best fits those features.

I believe ffmpeg does this, for instance - if you have SSE2, it uses one function, and if you have an AMD processor it uses another that uses AMD's instruction set, and if you don't have either it uses a generic one that uses standard x86 instructions.

install gentoo

How is that second one illegible?

Couldn't you use LLVM IR for this?

Rather than having a compiler switch that either compiles SSE or NEON instructions, you just use LLVM intrinsics.

For example with windows coming to ARM this seems like the superior option to either writing in a vm language, distributing different binaries or just x86 emulation.

Do strings ever stop becoming boring? Fuck I hate anything involving manipulating or inputting them

Again, nobody cares enough to do this.

It seems like you'd benefit from learning Python, or better yet, Perl.

Hello
who 's using i3 to dev ?

What are your problems with strings?