What practically annoys you on a regular basis in programming languages?

Started by
70 comments, last by Dawoodoz 4 years, 6 months ago
35 minutes ago, l0calh05t said:

Sorting members for reduced padding would be trivial. But the spec doesn't allow it 

I don't mean sorting. In this case int has alignment of 4 bytes, char of 1 and the double of 8. This may be simply packed as it is.

Advertisement
41 minutes ago, mawigator said:

I don't mean sorting. In this case int has alignment of 4 bytes, char of 1 and the double of 8. This may be simply packed as it is.

ah, ok, sure.

I use Javascript, specifically Node.js, at work to automate tests of a webapp. JS is really nice in some parts and really obnoxious in others. Since it annoys me the most I'll post mostly about it

What bugs (haha) me:

  • Most type coercion. It's OK for formatting text sometimes but causes annoying little bugs way too often
  • The Date class
  • NPM updates constantly breaking things. Both bugs and breaking API changes. And when it isn't NPM it's Chrome
  • How "this" is set up such that when writing OO code w code generation you need to call someObject.someFunction.bind(someObject) or else have "this" reference the wrong object
  • The bizarre threading setup requiring practically everything that's otherwise blocking to be async (or worse promises, or worse still callbacks)

I really like async/await for its intended use case. It's awesome to have code where I can do other work while waiting for what is normally a blocking IO operation.

The problem is in the test framework I have to use basically everything is a network call so everything is async. However almost every operation that is typically done in a test needs to be done sequentially. Forget an await or two? Have fun finding the resulting race condition. If I'm lucky the test will fail immediately. Otherwise the issue can lurk for days before suddenly cropping up.

In the past it was worse with lots of code amounting to a more nicely formatted version of this


return foo().then(() => return bar()).then(() => return baz());

 

Other/multiple languages:

  • Type erasure in generics in Java
  • Checked exceptions in Java. Especially in deep call graphs and especially especially when the exception represents a bug and shouldn't have been checked in the first place!
  • Certain people who catch exceptions and throw brand new ones destroying useful stack trace info needed for root cause analysis
  • Me constantly mixing up names of various standard operations between multiple languages. To add to an array/list is it push, append, push_back, add etc
  • Unity editor locking up completely without allowing me to stop the game if I accidentally write a tight endless loop somewhere
--------------------------Insert witty comment here!--------------------------
On 9/24/2019 at 3:41 PM, alvaro said:

Well, it does. You can refer to a member as `this->my_member'. You don't have to use it, but it's there.

This is probably due to the template system, because a template typename is usually a local variable under the hood of compilers. I used to maintain an open source compiler at work to make "this" explicit, but had to make an exception for template arguments because they only work when "this" is implicit by not being a run-time variable.

35 minutes ago, Dawoodoz said:

This is probably due to the template system, because a template typename is usually a local variable under the hood of compilers. I used to maintain an open source compiler at work to make "this" explicit, but had to make an exception for template arguments because they only work when "this" is implicit by not being a run-time variable.

I find your description [and almost everything about templates] confusing. Could you please post a short example of what you are describing?

Just now, alvaro said:

I find your description [and almost everything about templates] confusing. Could you please post a short example of what you are describing?

When a template class contains a variable of "typename T", T itself may be treated as a member variable even thou it's only stored in compile time. If you try to declare a varaible as "this->T foo" instead of "T foo", the run-time part of the compilation thinks that you're actually trying to dereference T as a stored varaible at run-time during a compile-time type declaration.


// Implicit this
template <typename T>
class Bar {
	Bar(T foo); // T is technically a local variable under the hood of some compilers
}

// Explicit this
template <typename T>
class Bar {
	Bar(this->T foo); // Won't compile because T is contained within an instanced scoped namespace
}

Using the correct namespace "Bar<T>" to reach T would defeat the purpose by ending up with "Bar<Bar<Bar<...>::T>::T>::T" to infinity.

- Redundant syntax and semantics (ie: syntax and semantics which a compiler always translates into same ISA).

- People complaining about lacking of a language features when it's clear that language was never meant to use in that context (eg: fixed ABI or garbage collectors for low-level/closed-to-hardware programming languages).

"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/
On 9/30/2019 at 4:59 AM, Dawoodoz said:

varaible as "this->T foo" instead of "T foo", the run-time part of the compilation thinks that you're actually trying to dereference T as a stored varaible at run-time during a compile-time type declaration

You seem to be confused about the distinction between types and members.

"T" in those examples is a typename, not a variable. The operator -> expects an rvalue and an lvalue (both of which are values, not typenames) as its operands, respectively. You might be mistaking it for the operator :: which expects a namespace or typename, and a typename or member, respectively.

If you have conflicts between a nearby T and a distant T, that's a design error you've made, not a syntax problem for the language to solve for you. If you need to expose the type T to users of your class, the correct syntax would be something like...


template <typename T>
class Bar {
public:
    typedef T value_type;
    value_type val;

	Bar(T foo); // Mutates 'foo' somehow and stores it in val.
};


// ...
template<typename X>
X use_bar(X reference) {
  auto transformed = Bar<int>( (int) 7 );
  auto minval = std::numeric_limits< decltype(foo)::value_type >::min();
  return minval + transformed.val;
}

 

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
3 hours ago, Wyrframe said:

You seem to be confused about the distinction between types and members.

"T" in those examples is a typename, not a variable. The operator -> expects an rvalue and an lvalue (both of which are values, not typenames) as its operands, respectively. You might be mistaking it for the operator :: which expects a namespace or typename, and a typename or member, respectively.

If you have conflicts between a nearby T and a distant T, that's a design error you've made, not a syntax problem for the language to solve for you. If you need to expose the type T to users of your class, the correct syntax would be something like...



template <typename T>
class Bar {
public:
    typedef T value_type;
    value_type val;

	Bar(T foo); // Mutates 'foo' somehow and stores it in val.
};


// ...
template<typename X>
X use_bar(X reference) {
  auto transformed = Bar<int>( (int) 7 );
  auto minval = std::numeric_limits< decltype(foo)::value_type >::min();
  return minval + transformed.val;
}

 

Sorry, but I'm not discussing best practices of C++ and you simply stated that all use of this should be implicit, which is not the requested feature of Python developers. I tried to explain why explicit this would be a bad design in a language that heavily uses templates, because then you would need to be explicit about template members as well for consistency. Template arguments are compile-time variables by the mathematical definition of having multiple possible values, even if they never reach the final binary.

9 hours ago, Dawoodoz said:

Sorry, but I'm not discussing best practices of C++ and you simply stated that all use of this should be implicit, which is not the requested feature of Python developers.

That's... not what I said. What I said was, your syntax is wrong, and your description of how you think the language and its compilers works, is wrong. I then illustrated how you could get the access to the "T" used in parameterization by giving it an explicit name, by using the type system the way it actually works.

 

Reading back to @l0calh05t's description, I think what you're talking about is this "explicit [self]"...


class MyClass(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

 

To which my counterpoint is, which of these functions has a `this` implicit variable?


int foo::bar(void) { return 42; }

int foo_bar(void) { return 42; }

To wit: you can't declare non-member functions while defining the interface of a member-possessing structure, so don't try... and when not defining the interface of such structures, you have to explicitly name the type to which you are defining a member by using :: syntax. So where is the ambiguity? Either the function declaration is inside a structure definition, or it has a :: in the name.

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

This topic is closed to new replies.

Advertisement