HackerTrans
TopNewTrendsCommentsPastAskShowJobs

kuhsaft

no profile record

comments

kuhsaft
·11 gün önce·discuss
Inflation can exist because of a lot of things: natural loss of value, resource scarcity, monetary policy, greed, etc. And it's even harder to make sense of with fiat currency.

> Seemed like a vicious cycle.

The issue is inflation and deflation both tend to be positive feedback loops. Inflation can promote behavior that promotes inflation. Deflation can promote behavior that promotes deflation.

Note that I use "tend to" and "can promote". It's all based of off assumptions on how people value things and their behaviors, as is all economic models.

> why prices HAVE to keep going up

It really doesn't have to. We do so because economic models show that we should because of the way we behave. But, we also behave the way we do because of the economic systems that we've designed.

Prices have to keep going up if you want a system that promotes endless consumption and growth in consumption.

It also lets you have a "non-zero-sum" economy, where it appears everyone is making a "profit". But, in reality it isn't.
kuhsaft
·11 gün önce·discuss
Yes, the laws of thermodynamics and laws of economics are empirical laws. But, the laws of economics are derived from human values, which are inherently subjective.

You state the choices as “illogical”, but those choices can be logical based off a different set of values.

Similarly, if you have a different set of axioms, you can build a different reasonable system on it.

It's like Euclidean geometry and Non-Euclidian geometry. They are both valid systems based off of different axioms. Similarly, the different economic systems are valid based off of different set of societal values.

You can also compare it to the ideal gas law. It's a law, but is based of a hypothetical ideal gas. Similarly, the economic laws are based off of a hypothetical society. The ideal gas law does not hold in all conditions, and economic laws do not hold in all conditions.

The economic laws are meant as tools to predict behavior. But ironically, we end up modifying our behaviors to fit the laws, and we weaponize the usage of "economic laws" to control the behavior of others.

We have economists complain how "that economic system doesn't work". Yes, it doesn't work with the laws that define your economic system, but it works with a different set of laws. We have people say, "that doesn't make sense because of X law". It's the other way around. The "law" doesn't make sense, because I value something different.
kuhsaft
·20 gün önce·discuss
I don’t see how it’s an improvement over C# structs. C# structs are value types so they are copied when assigned to a variable like primitives. There is no ambiguity because it’s a struct.

To avoid copying you have to explicitly declare a ref variable/parameter.

You can get the same immutability as value classes by using ‘readonly struct’s or ‘readonly record struct’s.

Java value classes are stranger because they are heap allocated by default and are only flattened/scalarized/stack-allocated when certain conditions are met. It’s the same as a class, but with extra restrictions, so that the JVM can possibly optimize memory layout at runtime.
kuhsaft
·22 gün önce·discuss
Even closer would be a C# ‘readonly record struct’. Though, it would be allocated on the stack unless you box it.
kuhsaft
·22 gün önce·discuss
Imo #4 is why it’s not that useful. If the data is larger than an atomic read/write op the data isn’t flattened and it’s a regular object with value equality and immutability.

You have to opt into force flattening, and then it’s the same as a struct, except it’s still heap allocated without escape analysis. You still have to implement synchronization to prevent tearing.

Static code analysis can give you a warning for potential tearing of structs.

DotNext.Threading provides Atomic<T> to enable high-performance atomic operations on structs without heap allocation.

https://dotnet.github.io/dotNext/features/core/atomic.html

The design of value classes just seems counteractive to its purpose: memory management. If I want to manage contiguous blocks of memory, let me manage contiguous blocks of memory. If I want to allocate something on the stack, let me allocate something on the stack.

The paradigms of struct vs object are too different and they’re trying to combine them into one.
kuhsaft
·22 gün önce·discuss
The C# equivalent to Java ‘value class’ would be a class with a struct encapsulated for data. The data is flattened and allocated on the heap like Java. Similarly, escape analysis could stack allocate the class at runtime, and they can be scalarized like C# structs.

Java ‘value class’ only flattens if the total size of the class data fits within an atomic read/write op. You can force it to flatten, but you may have tearing like C# struct.
kuhsaft
·22 gün önce·discuss
I hate to say it. But thats user error. The struct paradigm is different from classes. Structs are meant to be plain-old data types; simply a typed span of memory.

Structs are values, classes are entities with encapsulation.

The shape of the state would be structural. Whether or not the data in that shape is valid is behavioral.

Structs are useful when working with spans of memory.

Another example of a good usage of struct is Guid, which is 128 bits of data packed together.

The C# equivalent to Java ‘value class’ would be a class with a struct encapsulated for data. The data is flattened and allocated on the heap like Java. Similarly, escape analysis could stack allocate the class at runtime.
kuhsaft
·22 gün önce·discuss
Yeah, that’s a different issue. Statically-typed languages, including type-erased languages, are fine on the CLR. Dynamically-typed languages are a different beast.

I suppose DLR would be comparable to GraalVM/Truffle.

The difficulty of implementing a dynamically-typed language directly on the CLR and JVM are about the same. Though, it would probably be more efficient on the CLR with access to lower level operations for memory management.

I think an interesting project would be to implement a CIL interpreter on GraalVM.
kuhsaft
·22 gün önce·discuss
C# stackalloc returns a ‘ref struct’ which has certain restrictions and would be a Q-world type.

Java chose to go with an L-world implementation where everything is still a reference type on the heap, but memory management is more efficient via flattening. That’s why it’s a ‘value class’ and not a ‘struct’.

Primitive wrappers are scalarized into registers.

Stack allocated value types would have different semantics and is incompatible with the L-world implementation. Sure, they could implement it, but it would be the Q-world implementation that they decided to forego.

They can do automatic stack allocation for optimization via escape analysis as you mentioned. But, stackalloc is user allocated.

https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...
kuhsaft
·22 gün önce·discuss
All that to be bytecode backwards compatible, although behaviorally there are some breaking changes. See https://news.ycombinator.com/item?id=48597943
kuhsaft
·22 gün önce·discuss
There's also https://github.com/ikvmnet/ikvm that converts Java bytecode to CIL; essentially Java on CLR.
kuhsaft
·22 gün önce·discuss
I made a comment on my understanding of the difference in implementation here: https://news.ycombinator.com/item?id=48606173

The ramifications for backwards compatibility is that the JVM won't have CLR features such as stackalloc (allocation of blocks of memory on stack), ref parameters (pass-by-reference of stack allocated value types), and all the other low-level/high-performance programming features available in the CLR.
kuhsaft
·22 gün önce·discuss
> Now, one can argue that this is just smoke and mirrors with type erasure and it is but you can already put a Date into a List<Point> if you're so inclined because the JVM doesn't know the difference, hence type erasure.

And that's a massive problem that they're planing to solve with specialized generics.

> If I read the correctly, it means that if you have a Point value class then on the JVM level you'll be able to stuff any value class into there if you're so incline, just like with List<Point>.

I'm not sure what you mean. An L-type is an object reference. E.g. Ljava/lang/String, Lcom/org/CustomObject. The issue you're conflating is the erasure of List<T> to List<Object> and it's L-type Ljava/util/List.

> I prefer the Hack version

Hack/HHVM didn't have to worry about backwards compatibility.

---

The blog post does a pretty high level overview of the implementation, but my understanding of it is the following:

1. They are adding a new bytecode class flag for value classes. Bytecode descriptor for value classes are exactly the same (L-type).

2. Primitive wrapper classes will become value classes.

The difference from the CLR is that the JVM implementation is backward compatible with linked legacy bytecode. As they can accept a value class instance into their methods due to the same L-type. It's just additional metadata added to allow the JVM to stack allocate the class.

---

Separately, to handle generics:

1. Parameterized container classes will be flagged with a new bytecode to enable parametric attributes on initialization with the additional data of the parameters in the Constant Pool. Bytecode descriptor for classes are exactly the same with type-erasure, e.g. List<SomeType> erased to Ljava/util/List.

2. Initialization of parameterized classes are done with the additional metadata of the type argument stored in the Constant Pool.

3. The runtime does monomorphization of the parameterized class.

It doesn't seem too different to what the CLR does, i.e. runtime monomorphization. The difference is the JVM implementation is backward compatible with older type-erased code, i.e. the restrictions in Java due to type-erasure are exactly the same as before and the L-types don't change. It's just additional metadata added to allow the JVM to monomorphize the classes for performance.

---

In summary, value objects and specialized generics are backwards compatible with legacy bytecode. The JVM handles the compatibility. Of course, the newer bytecode is not forward compatible with older JVMs.
kuhsaft
·23 gün önce·discuss
Not necessarily. You can ignore the reified generic system in the CLR and monomorphize it in the CIL output for your language. Debugging for users is usually a nightmare though due to the monomorphization. The benefit of a type-erased runtime is the interop between the languages built on the runtime.

The monomorphization of CLR generics is what NativeAOT does, though it doesn't support some C# features.

TypeScript is essentially C#, but with type-erasure and lacking the low-level struct & pass-by-reference features.

I do think the C#/CLR struct implementation is better though.
kuhsaft
·23 gün önce·discuss
I mean, the language is what it is. But, it definitely constrains the language developers. Especially when considering interop with other JVM languages.

That being said, it is easier to write a language on top of the JVM with good interop, since there are less ways to implement features. Essentially, your language has to interop with Java.

And it is harder to have good interop between CLR languages because there are more ways to implement features. Essentially, your language has to interop with C#.
kuhsaft
·23 gün önce·discuss
I don’t think that’s the case. You can absolutely implement a type-erased language on top of the CLR. Your language will just have the same constraints of a type-erased language like Java.

Having reified generics in the CLR just lets you store more type information. There isn’t much of a trade off for CLR end-users.

Compare this to the constraints and workarounds that Kotlin and Scala have due to type-erasure on the JVM.
kuhsaft
·23 gün önce·discuss
The gotcha is the potential boxing of structs onto the heap, but that can be avoided using `ref struct`s.

https://news.ycombinator.com/item?id=48599273
kuhsaft
·23 gün önce·discuss
Like @layer8 said, pass by copy and pass by value are the same.

C# copies C++ behavior where you can pass a struct by value or reference, and you can mark the parameter as readonly. C# also has in/out parameters. Essentially, you can program in C# exactly like you would in C++.

https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...

The footgun with C# structs are that you can accidentally box them onto the heap. To avoid that you can define `ref struct`s that cannot be boxed. `ref struct`s follow the C# disposable pattern.

https://learn.microsoft.com/en-us/dotnet/csharp/programming-...

https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...
kuhsaft
·geçen ay·discuss
Cell phone towers and communication systems have backup power for emergency communication during power outages.

If you have backup power for your router and ONT/Modem, you should also still have internet service during a power outage. The ISP-owned ONT for a place I lived had a little lead-acid battery attached to it, and during power outages I still had internet service.
kuhsaft
·2 ay önce·discuss
> On the one hand, you are right, and I rather meant "not exploitable", since technically the vulnerability is still there.

And I'm fine with that. I think, the Qubes OS notices should use that terminology as well. Though, some of the vulnerabilities are exploitable, if you don't follow the Qubes OS guides to the T.