|
Thanks to the newsletter article I finally write my very first own source code generator, yea!
I found none of the resource on the topic I found were both simple and super helpful, but the cumulative tips in all of them finally unlocked the skill for me!
Turns out it's very simple (the main hurdle is that your generator library need to target .Net Standard 2.0).. someone need to write a "source code generator for dummy" article distilled to the essential!
(hey, maybe that's an idea hey?)
Anyway... I still am left with one.. conundrum?
I made a .resx to C# code generator. I know those exists out of the box, but the resulting class doesn't support static binding event if the current culture change, which is annoying with the live culture update support in my application.
I have a large chunk of code to enable live culture update, but I thought, wouldn't it be nice if I could have a different C# resource class hey? And now I have!
my conundrum is, the default resx class's property looks like that
internal static string About {
get {
return ResourceManager.GetString("About", resourceCulture);
}
}
whereas mine looks like that
public static string? fsf { get; private set; }
public static string? hello { get; private set; }
public static string? name { get; private set; }
static partial void UpdateValues()
{
var resources = GetDictionaries(Culture);
fsf = GetResource("fsf", resources);
hello = GetResource("hello", resources);
name = GetResource("name", resources);
}
so the the default class pay a (negligible) cost on every property access, and my code pay another (negligible but bigger) cost on resource change (but none on property access).
and I keep wondering, which one is the best?
for context, this class is primarily used through databinding to inform a WPF UI.
modified 7-Dec-21 19:19pm.
|
|
|
|
|
I like MS's for the modifiability but assuming yours is generated I guess it doesn't matter so much.
Why the nullable string type though? It's already a reference type. If they're all strings I'd ditch making it nullable to keep it simple. Then you can just use a basic null check on it. Unless there's some reason for it I don't get.
I wouldn't care about the performance unless you're databinding to a real time graph or something (which I've done)
Dictionaries are pretty quick though but the main issue I see with your UpdateValues() routine (given I don't fully understand what it accomplishes) is that if you have a lot of resources it will end up being slow.
Have you considered using Lazy<T> and loading on demand on a property by property basis? Lazy<T> Class (System) | Microsoft Docs[^]
You can dump one behind each get accessor so it loads the resource the first time on demand. That way you're only loading what you use, and you're not potentially causing a burp in your application's responsiveness when UpdateValues() is called for a lot of resources.
But then I'm spitballing, not having seen all of the code.
Real programmers use butterflies
|
|
|
|
|
I decided my option is better.. because it's better to waste (negligible) time on user action (when they change the current culture) instead of while simply viewing data.
honey the codewitch wrote: Why the nullable string type though?
It's just the new syntactic sugar with nullable reference type (which is just a compiler hint, not a runtime truth). Arguably it's true they wont be null because the default culture dictionary will not be empty (with the way it's constructed). null string never bothered me, so I didn't give it a thought.. but yea.. it might a nice touch.
honey the codewitch wrote: Have you considered using Lazy<T>
Well this is clearly counter productive, because the whole point of this generator is that the culture might (will?) change. Lazy have fixed value!
(I particularly wants live change notification since I opened a software in a unintelligible foreign language and I tried to make it English, turns out I had to find the language menu, select "english" and restart... Thanks google or I would have given up)
What you might suggest (and was contemplating) is to have my properties like so instead. Which remove the need for UpdateValues() , this is also more like the MS one is doing it.
public static string? hello => GetResource("hello", GetDictionaries(Culture));
modified 7-Dec-21 22:01pm.
|
|
|
|
|
I didn't realize your culture changed over the life of the application.
You could still do this, but you'd just have to reset your lazy init. If Lazy won't let you do it you can make your own poor man's lazy using lock(object) {} but you don't even need to do that unless your object will be accessed from multiple threads.
If it's not, you can just do
if(myres==null) {
}
return myres;
and then in your update routine you just set myres to null.
Real programmers use butterflies
|
|
|
|
|
mmm... I guess this is a (negligible) over my (negligible) update, which might save a significant amount of negligible time!
mmm.. worth it!
|
|
|
|
|
new generated code thanks to you!
putting it all, just for fun.... (the other partial file is always the same and jut copied from a generator resource)
public partial class TestResource
{
public static string fsf => _fsf ?? (_fsf = GetResource("fsf", GetDictionaries(Culture)));
public static string hello => _hello ?? (_hello = GetResource("hello", GetDictionaries(Culture)));
public static string name => _name ?? (_name = GetResource("name", GetDictionaries(Culture)));
private static string? _fsf;
private static string? _hello;
private static string? _name;
static partial void UpdateValues()
{
_fsf = null;
_hello = null;
_name = null;
}
static TestResource()
{
AddCultureDictionary("", new Dictionary<string, string>
{
{ "fsf", "ffs" },
{ "hello", "hello" },
{ "name", "name" },
});
AddCultureDictionary("fr-FR", new Dictionary<string, string>
{
{ "fsf", "nom de dieu" },
{ "hello", "salut" },
{ "name", "nom" },
});
}
}
modified 7-Dec-21 22:24pm.
|
|
|
|
|
Sweet. Glad to help.
Edit: I was thinking of the case where you do like microsoft and put every error message as a resource. In resource files like that you have hundreds or thousands of resources, and the above code will handle it much better than trying to load them all at once.
I figured it was worth it because this is a code generator, so the uses of it are somewhat open ended. IOW some day someone (maybe you) will use it to generate a particularly large resource and you'll be glad it works this way. =)
Real programmers use butterflies
|
|
|
|
|
In fact... your comment scratched a itch.. and I made a new generator that use an underlying ResourceManager (like Microsoft) instead of static dictionaries! yeah!
Super witch to the rescue!
|
|
|
|
|
How about generating methods for resource strings with placeholders?
For example, if your resource string Greeting contains "Hello, {0}. The date is {1:D}." , your code could generate something like:
private static string _greeting;
public static string Greeting(object p0, object p1)
{
string value = _greeting ??= GetResource("Greeting", GetDictionaries(Culture));
return string.Format(value, p0, p1);
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
bah, the class is mostly here for live databinding of resource string in WPF UI. My class fire the static change event supported by bindings! (unlike Microsoft one, obviously)
|
|
|
|
|
This may have been on here earlier, but a quick search did not find it.
Carrying out a payment with Visa requires about 0.002 kilowatt-hours; the same payment with bitcoin uses up 906 kilowatt-hours, more than half a million times as much, and enough to power a two-person household for about three months.
The rest of the article seems well-written.
source: Blockchain, the amazing solution for almost nothing - The Correspondent
|
|
|
|
|
|
It's because Ethereum and Bitcoin are based on an already legacy consensus algorithm (Proof of Work). Several better alternatives were devised (if you google blockchain consensus algorithms, you gonna find a bunch of them).
How proof of work works is basically guessing a number (hash), so whoever guesses first, gets the transaction reward. That guess is then validated by the remaining of the network to "prove" it's validity. Because guessing takes resources (computational power), it's not easy or cheap to fake a transaction and convince the network of it. Because to fake the latest "block", you would need to recalculate all the blocks behind it (that's where block"chain" comes from). Every new block's hash is based in the previous block.
So each new block makes it harder to overwrite the network. It's expensive and you sill may not be able to convince the rest of the network, it's not a wise investment. Very likely you will not succeed (otherwise bitcoin and etherum would have been taken over already).
Problem comes when the network grows (in nodes and transactions). The network adjusts itself and increases the difficulty of the guess, because more people are trying to guess. Instead of trying to guess a number from 1 to 10, you start needing to guess 1 to 100, then 1 to 1000, so on and so on. And that's when things become wasteful on Proof of Work based blockchain networks.
So the problem is that Proof of Work does not scale well, driving the energy costs up. Other consensus algorithms such as the one Ethereum is trying to adopt (Proof of Stake) does not rely on computing power to strengthen itself. The miner instead stakes wealth (for Ethereum, it's Ether). So instead of guessing you need to put your valuable crypto on the block pot instead of spending your valuable energy trying guess how much is in the pot. That is what protects the network from attacks. You need to stake a lot of money on an attack and if you're not successful you're going to lose it all.
The challenge of "upgrading" (to be more precise, is to change the algorithm for mining and validation), which Ethereum has been trying to do for years is that you actually need to convince the majority of the network to flip the switch at the same and synchronize it well, otherwise it will fail or interrupt the network. So it's quite challenging to change something in the network once it's widely stablished.
To alcohol! The cause of, and solution to, all of life's problems - Homer Simpson
Our heads are round so our thoughts can change direction - Francis Picabia
|
|
|
|
|
Very interesting details. Thanks for sharing.
|
|
|
|
|
A couple of years ago, against my better judgement, and for no good technical reason, just that the customer insisted on blockchain, we implemented an ethereum based payment system for both an online and in-store retail system. We had some supposed experts from the Ukraine working on the ehtereum/blockchain side and they gave us a json rpc API to communciate with to make our lives easier since we weren't working in javascript and didn't know anything about ehtereum/blockchain really.
When we eventually got the initial system working it took almost 15 minutes for a block to be confirmed, and a payment to therefore be considered complete (or at least recorded in a way that was good enough to avoid potential fraud/theft/accidental transaction loss etc). Imagine buying something in a store and having to wait 15 minutes for your payment to go through. Needless to say that didn't work.
I'm not 100% sure what the blockchain team did to solve this, but I think they put some sort of persisted cache in front of the blockchain with some retries back into ethereum if the initial block didn't commit or something. So basically papering over the the cracks in an unnecessary system.
I still can't stop myself shaking my head when I think about it.
|
|
|
|
|
Great story & that really is a head-shaker.
The point of this entire thing is: instantaneous, verifiable transactions.
But I'm probably just wrong.
|
|
|
|
|
The "distributed" nature of the thing is an illusion; it's a massive duplication of effort.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
Distributed duplication?
Global Distributed database with many read replicas and one random write replica?
To alcohol! The cause of, and solution to, all of life's problems - Homer Simpson
Our heads are round so our thoughts can change direction - Francis Picabia
|
|
|
|
|
See my response below. As if blockchain could only be done that way. Which is not true. That's Blockchain alpha, which is bitcoin and etherum. I see many articles like this that portray a very incomplete picture of blockchain and are usually very biased our misinformed.
To alcohol! The cause of, and solution to, all of life's problems - Homer Simpson
Our heads are round so our thoughts can change direction - Francis Picabia
|
|
|
|
|
David O'Neil wrote: 906 kilowatt-hours, [...] enough to power a two-person household for about three months. That is assuming you are either living in a rather warm climate, or you do not use electricity neither for hot water nor room heating.
The average Norwegian household uses 16 000 kilowatt-hours a year, 1333 kWh per month on the average. Heat pumps are used everywhere, we switched to LED based light years ago. (Before the heat pump / LED takeover, the average poser consumption was 20 000 kWh/year.)
906 kWh / 3 months is 10 kWh a day. I spend that much even midsummer, on cooler/freezer, hot water, cooking, washing machine, dishwasher and various other electric equipment and tools, and of course a little light for basement/attic or at late night.
|
|
|
|
|
My understanding was that there is a building built with BTC Miners at it's core to generate heat for the building in a cold climate.
Talk about re-use. Proof of work, for "creating" BTC was an important part of the thesis. Eventually all BTC will be created. Then the only money available will be fees for recording transactions. This will be the opportunity to reduce the energy consumed, but the challenge is keeping the miners to keep the network secure.
You saw the drop in BTC, etc over the last few days. I joked that ETH didn't drop as much, because the WHALES (big players/sellers), could not afford the ETH fees! (ETH is so expensive as a network, that it's success is literally killing itself. I am already on 2 other ETH forks to reduce those fees).
Bugs have a WHOLE different meaning when the software is protecting a TRILLION DOLLARS of other peoples money!
The free market is already responding. But blockchain will survive. Square (now block), and PayPal, and many banks are YEARS into their development efforts.
It's the internet era, all over again!
|
|
|
|
|
Thank You An enlightening article Maybe selling the ugly gorilla NFTs mentioned in today's news letter will pay the electric bill By the way here is a suggestion as to how to possibly pay all your electric bills for a very long time Write some AI code which generates thousands of NFTs of ugly gorillas
|
|
|
|
|
As you say, the rest of the article seems well-written, but that figure of 906 kWh per transaction must be nonsense: the figure is not substantiated, and is probably referring to the cost of mining a block of transactions (~3,000 as of 2019).
|
|
|
|
|
|
|