
CPY – Code C/C++ with no redundancy - axiomdata316
https://github.com/vrsperanza/CPY
======
ktpsns
"CPY" seems to concentrate on syntax. I would not call an expressive syntax
"redundant". From my perspective, redundancy in programming arises due to the
lack of programming skills or a good preprocessor, especially probably in the
C/C++ world where codes are more likely tailored for speed.

The problem with (essentially) replacing the C/C++ syntax with a more
lightweight (pythonic) one was already mentioned here in the threads: There
will be a lot of corner cases which the CPY compiler does not understand.

~~~
asfasgasg
Redundancy in C++ chiefly arises from textual inclusion as the mechanism for
communicating about the capabilities of other modules. It's not because of a
bad preprocessor or programming skill.

~~~
ktpsns
Can you give an example of what you refer to?

In my impression, most of the redundancy in the C world comes from the
header/code seperation, i.e. all the signatures are repeated. Another level of
redundancy was added by C++ templates where one quickly needs to write lengthy
expressions, but the newer C++ standards resolved much of that thanks to the
"auto a = b" type keyword or the "use X = Y" definitions.

Note that "CPY" addresses none of these issues.

~~~
rileymat2
I must be one of the few that like the header/code separation. When dealing
with plain text, I get a more concise view of what is going, as well as a view
of what should be used by other modules.

~~~
s_ngularity
The problem with the separation is mainly with making changes to code, not
with reading the code as it currently exists.

This problem is avoided at no cost in Go, where an external tool can be used
to get the same concise view of all of the function types that you like,
without needing to manually create and update header files.

~~~
nixpulvis
Writing code takes effectively no time, reading and reasoning is the primary
concern (for me anyway).

------
RcouF1uZ4gsC
It seems a lot of cpy features are covered by C++ and/or libraries.

For deduced types you can do

    
    
        auto a = 10;
        auto b = a;
    

And not have to mess with known.

For multiple return types you can do structured binding and make_tuple.

    
    
       auto [a,b] = func();
    

Where func is

    
    
       auto func(){return std::make_tuple(1.5, 3);}
    

Using a loop, you can use boost::irange

    
    
        for(auto i: irange(0,10)){
    
    

For the output stuff, you can use fmt
([https://github.com/fmtlib/fmt/blob/master/README.rst](https://github.com/fmtlib/fmt/blob/master/README.rst))
which is on track for standardization.

    
    
        fmt::print("{} {} {} ", a,b,c);
    

Overall most of the problems that CPY implies have pretty good solutions in
C++ without the pain of another pre-processor

~~~
ktpsns
This is very true. It would be elegant if "CPY" compiled to these newer C++
features (or boost).

~~~
vrsperanza
That is exactly what it does

------
fjfaase
This suggests that large parts of C/C++ can be 'simplified', which I think is
a falacy, resulting in CPY to be a proper subset of C/C++. Already the
introduction of a keyword like 'known' shows that the simplification is not as
simple. I suspect that many new keywords needs to be added to support the full
scope of C/C++ within CPY.

~~~
cjalmeida
If you think of cpy as high level glue code for "pure" c++ functions, this
might work.

I don't like decisions like implicit << and >> for cin, cout. Too much magic
for me.

~~~
drenvuk
Honest question, why do you consider implicit << and >> for cin,cout to be too
much magic?

~~~
saagarjha
It's a misappropriation of an operator. C had a "definition" for them, and
this completely disregards that definition. It's one of the biggest things
people cry about when custom operators are brought up in other languages,
because C++ really dropped the ball here in using operators in a sane way.

~~~
kevin_thibedeau
And yet we had a few decades of magic 0 literals that transmute into pointers
until we finally got a proper nullptr. There's some grade A impurity built
directly into the core language and hard to avoid unlike the std lib.

------
hzhou321
I use MyDef to achieve most of features `cpy` is trying to introduce:

    
    
        # t.def
        page: t, basic_frame
            module: c
    
            a=10
            b=a
            $dump a, b
    
        $ mydef_run t.def
        PAGE: t
          --> [./t.c]
        gcc -std=c99 -O2 -o./t ./t.c  && ./t
            :a=10, b=10
    

I didn't introduce `known` keyword. If I want straight C code passthrough I
simply append semicolons.

MyDef is a general preprocessor, so I need the page and module declarations to
tell what file and types I am generating. It always shows the command it
actually runs, so there is no magic. And it does not pretend to replace C. It
always produces `.c` file for debugging or merging with existing workflow.

As long as MyDef is strictly preprocessor, it is purely complementary. If you
prefer straight C/C++ at places, just use straight C. If you have questions on
what MyDef syntax does, just read the C output.

It does pose some restrictions on the C I write. I do not write long
statements in multiple lines and rely on my editor to softwrap the lines. Long
lines are difficult to read anyway with or without splitting and soft-wrapped
lines are not much difficult to read anyway. I often can avoid long lines by
refactoring. In rare cases that lines still end up too long, I leave it as is
to remind me that it needs further work.

Sometimes I need import third-party raw c code during a progress of
refactoring or code digesting. MyDef has template construct to quote them
directly.

MyDef: [https://github.com/hzhou/MyDef](https://github.com/hzhou/MyDef)
output_c:
[https://github.com/hzhou/output_c](https://github.com/hzhou/output_c)

~~~
abenedic
Last year I learned about MyDef. I like the basic concept, but it did not fit
my use case unfortunately. I also am not well versed in Perl and at least at
the time the documentation of the internals was too sparse for me, so I was
not able to adapt it to fit my needs. But I do think people should look more
into the idea of using preprocessors like MyDef and CPY.

I, like everyone else who has the need, wound up writing my own C++
preprocessor. I think there is a lot of merit to the idea of having a low
level base language which is machine independent and using a high level
syntactic sugar over it.

~~~
hzhou321
I lately do realize that to be comfortable with MyDef, one need be versed in
three languages -- the language you are writing, MyDef, and Perl. People seem
more welcome to the idea of having new language replacing the old rather than
a solution of taking advantage of existing tools. I think this is the same
barrier of Knuth's literate programming. Despite how I find how much MyDef
make life easier, others will not see the same if not ready.

What I am hoping for is conversation. With conversation, I can have the
motivation for documentation and others can understand and the barrier may
dissolve.

------
abenedic
The redundancy that matters to me is writing code for yet another
serialization or pretty printer. I couldn't care less about syntax.

I am a firm believer that the compiler should do as much work as possible, no
matter the time it takes. I think the compiler ought to generate default
pretty printers for structs and unions on its own, that may be overridden.
Same for serialization formats and so on. The C++ compiler has more than
enough information to make programmers lives more convenient at no added
runtime expense, and I would be very willing to eat the compile time cost.

I wound up having to write my own preprocessor for C++ to automatically
generate structure metadata for an embedded application. I wish there was more
of a push for general preprocessors in this direction.

------
quietbritishjim

        // CPY loop to iterate from a down to b, c at a time
        for i a b -c
        
        // For comparison: pure C++11 and boost
        for(auto i : irange(a, b, -c))
    

After CPY removes redundancy to this extent, sure there's still enough
information for a compiler to parse this, but there's not enough information
for _me_ to parse this. Remember that you spend a lot more time reading code
than pressing buttons on the keyboard, so the number of characters you need to
type is pretty irrelevant to your productivity.

Maybe I'm getting too caught up on the name, which suggests a Python-like
experience, which CPY definitely not. If anything it is less like Python than
C++! Sure it has the indentation vs braces thing, but that is probably one of
the least important reasons why Python is so readable. A more important reason
is the excellent visual cues in the syntax, and forcing you to spell things
out e.g. with named parameters; "explicit is better than implicit". CPY seems
to strip out visual cues, as shown above, by its four print functions that are
cryptically called !, !!, ? and ??, and by the fact that it's even harder to
spot function declarations in CPY than in C++.

------
gumby
The feature I like here is an old Common Lisp feature: accepting as many
returned values as you’d like. C/C++ allows you to accept 0 returned values
without special syntax, but in all other cases you have to be careful. Whereas
in CL you can return as many values as you like and the caller can accept as
few of them as it likes with no extra overhead.

In c++17 you can sort of do that but you still have to unpack the whole tuple
(and the caller has to make one instead of simply doing ‘return a, b, c;’ to
return three values. I understand why the C++ committee didn’t make this
change (it would break valid programs, though there are likely few to none of
them).

~~~
fooker
Having to write :

return {1, "42", '2'};

seems like a fair trade-off to me. Btw, this is already implemented from
c++11.

------
yitosda
I think this could be more interesting if it was a superset of C++ that
allowed for brevity in some cases. Something that could:

1\. Act as a preprocessing step for any existing C++ file

2\. Output perfectly servicable C++ in the case where you want to move away.

Additions like the "known" keyword make this look badly thought out.

In any case, the weakness of C++ in most cases is compilation speed, not
typing speed. Even in the ideal case I can't see this adding more value than
it detracts (preprocessing speed + buildsystem complication + extra
dependency).

~~~
jakear
One nice feature is writing your class interface/implementation all as one and
the system splitting it into .h .and .cpp. Especially if it can be set to do
things like the "pimpl" pattern.

I'm probably a minority in the C++ world, partially because I don't have a
powerful IDE, but I tend to write everything in .h and only split it out later
on, which gets annoying.

~~~
gmueckl
If compiler times and ordering of declarations were easier to handle, I would
probably change my code to live in headers only. Keeping headers and sources
in sync is annoying. And the compiler also gets amazing optimization
opportunities if it can see all of the implementation code.

~~~
jjuhl
As far as optimizations go, LTO (Link Time Optimization) solves a large part
of that problem

------
kyberias
One basically needs to implement perfect C/C++ parser in order to accomplish
this with sufficient accuracy. Does CPY implement that? No.

~~~
pubby
libclang to the rescue! (which CPY doesn't use)

------
zorkw4rg
I would love to be able to write C++ without having to write header files,
there is an insane amount of redundancy between header/sources in any C++
project. I don't even care about anything else, that would be the most
important thing this tool should support flawlessly.

~~~
TheCabin
You could simply write header-only code (see keyword 'inline').

------
arithma
A superset of C++ would be unwise: same issues as those C++ inherited from C!
I imagine something similar to CPY could be created for different domains
like:

\- Pure functional style (Haskell subset that is usable from C++)

\- GC'd higher level gluing code (calls C++ but maybe not necessarily callable
from it)

Am sure others are more qualified for suggestions, but I imagine other subsets
like some for interfacing with representing relational data querying,
different concurrency models (like Go, Erlang...)

Is this a sane suggestion?

------
xtrapolate
Very interesting! On a slightly related note, I'd personally love to see more
"C++ variants" (for lack of a better term) out there. By that, I'm referring
to ecosystems/languages that are essentially a
simplified/abstracted/modernized version of C, but ones that also still allow
you to "break out" back to classic C at will. Thank you for sharing.

~~~
tzahola
Objective-C? D?

~~~
xtrapolate
Correct me if I'm wrong, but Objective-C's ecosystem is very much Apple-
centric. Things in that regard have only started changing fairly recently.

~~~
tzahola
Apple-centric? The libraries in iOS and macOS, for sure. However, the language
itself can be used anywhere where GCC is available.

------
andrepd
So, just syntactic sugar for frequent use cases (stdin/stdout with iostreams,
returning tuples)?

------
mulur
So CoffeeScript meets C++?

------
kazinator
> _... without redundancy. Curly brackets are implied from identation_

I.e. nesting information is repeatedly encoded into every line. Nope, no
_redundancy_ here, move along!

------
aetherspawn
Hey, cool project!

I’m not sure I agree that the input is more readable, but good nonetheless.

If I had the choice, I’d move the syntax closer to Haskell do-notation than
Python, but that’s just me.

------
jhasse
Similar idea: [https://bixense.com/coffeepp](https://bixense.com/coffeepp)

------
zmmmmm
Reminds me of Groovy vs Java ... although seems limited to syntactic sugar
mostly rather than adding functionality.

------
alacombe
Implicit variable declaration, multi-value return, so semicolon /
parenthesis... sounds a lot like Golang.

~~~
Yoric
Sounds a lot like most languages designed during the last 20 years (or 50
years if you include academia), actually :)

------
kasajian
Damn it.. this was my idea. I was going to call the language "raw" x(

------
ndh2
What about debugging? Looks like it's Linux-only.

------
partycoder
Good luck setting a breakpoint.

