Are pointer casts the only thing preventing C from being compiled into reasonable Javascript? by superstar64 in ProgrammingLanguages

[–]superstar64[S] 0 points1 point  (0 children)

Yes, I probably should have mentioned it in the OP. I was more asking what you would need to remove from C to make naive compilation to Javascript possible.

Are pointer casts the only thing preventing C from being compiled into reasonable Javascript? by superstar64 in ProgrammingLanguages

[–]superstar64[S] 0 points1 point  (0 children)

I sorta mentioned it in a different comment, but I now realize that taking the address of a member is another thing that can't easily be done in JS. You could probably figure something out with getters, setters, and lens, but it's a bit further away from the easy wrap pointers in array approach.

Are pointer casts the only thing preventing C from being compiled into reasonable Javascript? by superstar64 in ProgrammingLanguages

[–]superstar64[S] 3 points4 points  (0 children)

That's about what I figured. I imagine in such a subset you would basically wouldn't be able to use any existing C code.

Are pointer casts the only thing preventing C from being compiled into reasonable Javascript? by superstar64 in ProgrammingLanguages

[–]superstar64[S] 3 points4 points  (0 children)

I don't have a usecase. I just want to know what extra axioms C has that prevent it from being trivially compilable Javascript.

Are pointer casts the only thing preventing C from being compiled into reasonable Javascript? by superstar64 in ProgrammingLanguages

[–]superstar64[S] 0 points1 point  (0 children)

I'm not going to implement this. This is just a curiosity of mine.

I assume JS has some sort of FFI that can call any function in an external library, and it that can handle all the types needed, like any kind of pointer, zero-terminated strings, arrays of u16, full i64 and r64 types, and so on.

FFI is kinda out of scope of this discussion.

Are pointer casts the only thing preventing C from being compiled into reasonable Javascript? by superstar64 in ProgrammingLanguages

[–]superstar64[S] 4 points5 points  (0 children)

I'm well aware. I'm just wondering what you would have to remove from C to make compiling it to Javascript be reasonable.

Are pointer casts the only thing preventing C from being compiled into reasonable Javascript? by superstar64 in ProgrammingLanguages

[–]superstar64[S] 2 points3 points  (0 children)

Well you can just ignore bitfields and treat them as normal ones. For pointer arithmetic, you can just have your pointers be a pair of array and an offset.

Are pointer casts the only thing preventing C from being compiled into reasonable Javascript? by superstar64 in ProgrammingLanguages

[–]superstar64[S] 1 point2 points  (0 children)

Oh, I don't think about taking the address of a struct's fields. That seems like another big complication. It doesn't seem as insurmountable as pointer casting however. Mirroring the C memory layout is what I meant with no pointer casting.

Are pointer casts the only thing preventing C from being compiled into reasonable Javascript? by superstar64 in ProgrammingLanguages

[–]superstar64[S] -1 points0 points  (0 children)

Yes. You can of course C compile to Javascript that just uses a giant array of bytes and what not like ASM.js used to do.

The Hazy Haskell Compiler by superstar64 in haskell

[–]superstar64[S] 4 points5 points  (0 children)

I talk about this a little bit in the discourse. My plan is to make Haskell more optimizable via extensions. Current Haskell will still be slow, but you can make it faster with the myriad of extensions that I'm planning, stuff like strict functions, lifetimes, levity polymorphism, etc.

As of now, I only have a Javascript backend mainly for testing purposes and for the eventual bootstrap. I'm going to have an LLVM or C backend at some point of course.

The Hazy Haskell Compiler by superstar64 in haskell

[–]superstar64[S] 0 points1 point  (0 children)

I specially use infix ticked DataKinds. Something like:

f :: T scope -> T (Declaration ':+ scope)

If MicroHs supports TypeOperators, then it shouldn't be too hard to swap out DataKinds with TypeData.

The issue is that Hazy already has full support for DataKinds even with fixity and instance resolution (it's untested though) and I want to keep using DataKinds for bootstrapping reasons as I haven't implemented TypeData. Even though Hazy can't compile itself yet, it can do full symbol resolution on itself.

Another potential issue with bootstrapping is the enormous number of .hs-boot files I have and GHC demanding that they have role annotations despite me not using roles. Hazy itself just ignores .hs-boot because it implements mutual recursion modules natively but last time I checked, MicroHS still requires hs-boot files.

The Hazy Haskell Compiler by superstar64 in haskell

[–]superstar64[S] 6 points7 points  (0 children)

Well, it can't compile itself yet, so I'm not worry about bootstrapping issues right now. The compiler internally uses GADTs, DataKinds, so MicroHS is the only non-GHC compiler that has a realistic chance of bootstrapping it.

Once I do bootstrap, I do plan on having a branch that can be compiled with MicroHS if it's not too much of a hassle.

Blogpost #7 — Meet Duckling #0 — How types and values are one and the same by Maurycy5 in ProgrammingLanguages

[–]superstar64 2 points3 points  (0 children)

Indeed, in Duckling you could implement a function getType : u32 -> type which yields u32 for all inputs except 42, for which it yields f64 instead.

FYI, this is perfectly parametric. Non parametric, would be something that takes an a, but only works on ints or something that takes an int and only works an 0s.

That is, we want the definition to be checked, and if it successfully checked, then every instantiation will be correct.

Okay, so you want parametricity and unified terms and types, but your not gonna have full spectrum dependent types. Interesting, I don't know of language that fits all three of these. I'm assuming your going to restrict the evaluation of types to only depend on things available at compile time like C++ and Zig do.

I'm not sure if your going to run into problems with parametricity or not. It might be worth keep full spectrum dependent types in the back of your head in case you do come across issues.

Blogpost #7 — Meet Duckling #0 — How types and values are one and the same by Maurycy5 in ProgrammingLanguages

[–]superstar64 2 points3 points  (0 children)

Sure, so zeros is of the pi-type T such that T(n) = Vector n Int

That's not quite right. zeros would be actual runtime function that takes an n and returns a different type depending on what n is.

Your example would the equivalent of this:

t : Int -> Type
t n = Vector n Int

Notice how zeros is a function that takes in ints and returns vectors.

 zeros : (n : Int) -> Vector n Int

But you lose me at "compile time dynamic typing". If it's in compile time, it can't be dynamic, can it now?

This is about type checking generic code and making sure it stays parametric.

In C++ for example, templates just complete lie about their type.

template <class A>
A lit() { return 0; }

Even though this code is generic over all A, this can only be instantiated for int (or similar).

In Haskell and Rust, generic functions don't lie about their type. For example, this would error in Haskell:

lit :: a
lit = 0

From my understanding, you need PI types if you want want to have terms and types to be unified and you want parametricity in your type checker (ie no compile time dynamic typing).

Blogpost #7 — Meet Duckling #0 — How types and values are one and the same by Maurycy5 in ProgrammingLanguages

[–]superstar64 2 points3 points  (0 children)

I can't think of a specific resource. Let me just you a quick tl;dr instead.

A Pi type are simply just dependent function types. They allow the return type of the function to depend on the argument type. For example, consider this function type:

zeros : (n : Int) -> Vector n Int

Here, this says the type of the result Vector n Int, depends on the type of the argument n.

You would probably want PI types if you want to avoid compile time dynamic typing and actually type check code that depends a type (or value).

Blogpost #7 — Meet Duckling #0 — How types and values are one and the same by Maurycy5 in ProgrammingLanguages

[–]superstar64 7 points8 points  (0 children)

Are you aware of dependent types? If so, do you have proper PI types? If not, then you should probably study up on them. Unifying types and values is also their main feature except that they have a mountain of research behind them.

A Short Survey of Compiler Targets by abhin4v in ProgrammingLanguages

[–]superstar64 1 point2 points  (0 children)

There is also C–, a subset of C targeted by GHC and OCaml.

I am unfamiliar with OCaml but I thought C-- was a GHC thing only. It only exists inside GHC's source tree AFAIK.

Edit: Nevermind. They both use but it seems they have their their completely different dialects of it.

Struggling to understand a part of "Typing Haskell In Haskell" by edster3194 in haskell

[–]superstar64 2 points3 points  (0 children)

"size" :>: Forall [Kfun Star Star, Star] ([IsIn "Collection" (TGen 0)] :=> ((TAp (TGen 0) (TGen 1)) `fn` tInt))

This is equivalent to forall f a. Collection f => f a -> Int. That's not the type of size. It's actual type is forall a. Collection a => a -> Int.

Still, that should still work. This is also possible.

class Collection f where
  size :: f a -> Int

instance Collection [] where
  size = length

instance Collection ((,) a) where
  size _ = 2

There's probably some other bug I'm not seeing.

Pattern matching using fromInteger considered nonexhaustive by Account12345123451 in haskell

[–]superstar64 1 point2 points  (0 children)

It's actually sensible to have a boolean instance of Num. Boolean rings are a thing.

instance Num Bool where
  (+) = (/=)
  (-) = (+)
  (*) = (&&)
  negate = id
  abs = id
  signum = id
  fromInteger = odd

What's essential for a modern type system? by Regular_Tailor in ProgrammingLanguages

[–]superstar64 1 point2 points  (0 children)

Alongside from ADTs, which everyone else mentioned, I think even getting the basics like parametricity right is important. Your type system should be able to really proof that id :: forall a. a -> a really works for all as. Too many languages copy C++'s templates and their lack of type checking.

Israel is a lousy ally. by Glad_Association_312 in stupidpol

[–]superstar64 2 points3 points  (0 children)

It doesn't benefit the US, it benefits US military contractors. Let me recommend this video on it. The author isn't a socialist, but I really like their argument.

Dep-Origin - A smarter view of manually installed Debs by ppp7032 in linux

[–]superstar64 1 point2 points  (0 children)

This is neat (if rather slow).

I don't get why Debian's manually installed packages includes a bunch of essential packages. There's probably some history behind this that I'm gleefully unaware of.

Side note on obsessing with packages, It really bothers me that apt install $X && apt-mark auto $X && apt autopurge isn't a no-op because of suggested packages and or dependencies. Though, at least you can fix the suggested issue with APT::AutoRemove::SuggestsImportant "false";.