Extending GPT-3’s context window infinitely by storing context in GPT-3 itself or in secondary layers

Let’s give GPT-3 what it needs to power an AGI. Feedback is welcome.

Context

OpenAI’s GPT-3 is one the best (and most underrated) things that happened to mankind in 2020. It proved that it is possible for an AI to surpass the zero-shot and few-shot learning abilities of most humans on a huge range of general tasks, both logical and creative, and pass the duck test for human intelligence (aka Turing test) with flying colors.

The implications are profound, and provide a fresh look both about what it means to be intelligent, and the notion of agency. Indeed, what are we if not a machine predicting and merely obeying our next most likely action/thought based on the context window of our life and everything we’ve been exposed to, creating our own model of the world and acting upon it?

GPT-3 has also built its own model of the world, basically of how things (symbols, words and abstract concepts) relate to each other, in a comprehensive and accurate way no symbolic AI researchers/enthusiasts (myself humbly included) could have hoped for, or remotely anticipated.

We have this amazing model, which proves human knowledge can be encoded in a huge neural network, but today can only use it provided the context and expected response fit within 2048 tokens (expressed via language, only around 1,000 words). And most importantly, we cannot easily and efficiently teach it any new information the way we can teach a human intelligence (which is really the Holy Grail for AGI). Fine tuning and retraining the whole model open useful possibilities, but are far being the kind of one-shot feedback loops humans excel with.

Proposal

What about training a meta model that would learn where and how to best adjust GPT-3 parameters so they can “learn” new knowledge, preserved, contextualized and linked to the huge swath of existing knowledge already in the network?

For more modularity, what if given something we want GPT-3 to learn (an input), and GPT-3 itself, we could find how to modify the parameters of a secondary layer/model so that the combination of both layers produces an output that is consistent with the input provided?

Both the reward function and model evaluation benchmark could basically prompt the model itself to verify that the combined network is able to reliably and robustly regurgitate what it has been taught (not raw data memorization).

Context itself could therefore be taught, infinitely expanding GPT-3’s capabilities beyond 2048 tokens, and giving it the ability to create its own memory and evolving model of the world, one shot at a time, the way humans do (at worst with our same defects/limitations).

Contextual layers could be deeply personal (taught with all the stimuli we experience ourselves, language being a good start, the same way we could teach a human locked in a room via a console about our life by journaling what we hear, read, say and think), to generate an AI that knows almost everything about our life and could become the ultimate personal assistant/extension of self. It could also leverage layers at an organizational level (e.g. company knowledge), and the core, common mankind-level probabilistic knowledge we are willing to trust (e.g. GPT-3, the same way we trust Wikipedia).

Conclusion

What I propose here is the simplest mechanism allowing for an AI to find its way to modify only a small part of its existing model parameters to learn a specific input, without the need to retrain the model or change its architecture. I believe this is a key step in the right direction towards a more general AI able to learn, improve and contextualize its knowledge, and leverage it in a robust and scalable way.

I plan to work on this myself, but feel that it is such a big, important, challenging and potentially risky endeavor that I feel compelled to share it with the AI community and hopefully receive feedback/help from people with a better understanding of the technicalities and the necessary skills to help improve the idea and eventually try and implement it.

If you like the idea, and want to discuss, collaborate, or help, please comment here or reach out to me.

I’d like to thank GPT-3 for writing this conclusion (all the possibilities it suggested, based solely on what I had written before, were spot on).

This post was also published on Medium.

How to find all Gmail unlabelled messages: finally an official operator

I am happy to discover that a native way to filter unlabelled messages in Gmail was recently made available by the Gmail team, though it does not seem to be widely known yet.

The operators has:userlabels and has:nouserlabels achieve what previously required the concatenation of negative label conditions for all labels in your account (such as “-label:Stuff -label:OtherStuff”). The greasemonkey extension gmailUnlabelled certainly existed to automate the process. But it had to be potentially updated with each alteration of the Gmail UI and did not work well with non US locales.

As per the official documentation:

has:userlabels, has:nouserlabels: Finds all messages without any of your own labels (excludes automatic labels like inbox, spam, and trash). Since Gmail applies labels to individual messages, you might see results that appear to have labels; in this case, another message in the same conversation thread has had a label applied to it.

The simplest search expression to obtain all unlabelled emails in gmail (and exclude system labels as well) is henceforth the following:

has:nouserlabels -label:inbox -label:sent -label:chats -label:draft -label:spam -label:trash

For regular use, this dynamic search result can be saved using the “Quick links” feature available in the Gmail Labs.

Wheelchairs to become obsolete soon

I love this innovative way to rethink disabled people’s mobility:

Users would not look weirder than their counterparts riding a Segway.

Congratulations Tek! You are making the world be a better place for those who need it most.

Philosophie

La durée de la vie humaine ? Un point. Sa substance ? Fuyante. La sensation ? Obscure. Le composé corporel dans son ensemble ? Prompt à pourrir. L’âme ? Un tourbillon. Le sort ? Difficile à deviner. La réputation ? Incertaine. Pour résumer, au total les choses du corps s’écoulent comme un fleuve ; les choses de l’âme ne sont que songe et fumée, la vie est une guerre et un séjour étranger ; la renommée qu’on laisse, un oubli. Qu’est-ce qui peut la faire supporter ? Une seule chose, la philosophie. — Marc-Aurèle, Pensées, Les Stoïciens, Bibliothèque de la Pléiade, Gallimard, 1962, II (17) p.1150

Say hello to MySQL

Why does software so often fail to understand basic social conventions?

MySQL - Hello

Call and send SMS/MMS from your ZTE 3G modem

I recently wanted to use my cell phone sim card inside my 3G USB stick (a ZTE 3565-Z bought in Croatia), without losing the ability to receive (or make, though I generally use VoIP software for this) calls.

Given what these 3G modems were designed for (i.e. modem use), and a previous unsuccessful experience trying to make a landline call with my laptop internal 56K modem, I was not sure whether this would be at all technically feasible. Yet digging the web revealed that it did could work with specific hardward and software. I preferred to challenge rather than change my hardware, and therefore set myself up for a new quest, in the hope of finding the holy missing piece of software, if there was any.

And I eventually found an uncluttered dashboard (equivalent to Vodafone Mobile Connect or Gestionnaire de Connexion SFR), which worked perfectly both to access the Internet (at least with all the 3G service providers around the world I tried) and to receive/make calls.

The existence of this simple yet world changing software (for me) was somehow unveiled here on d-c unlocker forums (then also mentionned on this German website and here), with a link to download it. For those who have not heard of it yet, d-c unlocker is a brilliant piece of software that can unlock 3G data cards (and that works!).

Surprisingly, this state-of-the-art piece of software was released under Metfone’s brand, a Khmer (Cambodian) mobile and residential Internet provider. This must be why most of the countries in the area are considered as “emerging” or “pre-emerging”…

I now have the best smartphone one could ever dream of: a laptop connected to the Internet :).

Metfone UI

A tip to improve the performance of your Bloomberg API application

If you make a request for data which results in a lot of events generated by Bloomberg API (such as long historical intraday data request, or possibly real time subscriptions), do not use the pattern specified in the API documentation, as it may end up making your application very slow to retrieve all events. Basically, do not call NextEvent() on a Session object, use a dedicated EventQueue instead.

Instead of doing this:

var cID = new CorrelationID(1);
session.SendRequest(request, cID);
do {
   Event eventObj = session.NextEvent();
   ...
}

Do this:

var cID = new CorrelationID(1);
var eventQueue = new EventQueue();
session.SendRequest(request, eventQueue, cID);
do {
   Event eventObj = eventQueue.NextEvent();
   ...
}

This simple change may yield performance improvements by an order of magnitude (or not, as the API is known to not be particularly deterministic…).

Recursive algorithm to generate all combinations of elements in successive enumerables

If you need to flatten ordered enumerables, that is taking one element of each enumerable, in order, to flatten a combination, here is a quick solution in C# and VB.NET, accompanied with an example:

Code in VB.NET:

Private Shared Sub GetCombinationsRec(Of T)(sources As IList(Of IEnumerable(Of T)), chain As T(), index As Integer, combinations As ICollection(Of T()))
	For Each element As var In sources(index)
		chain(index) = element
		If index Is sources.Count - 1 Then
			Dim finalChain = New T(chain.Length - 1) {}
			chain.CopyTo(finalChain, 0)
			combinations.Add(finalChain)
		Else
			GetCombinationsRec(sources := sources, chain := chain, index := index + 1, combinations := combinations)
		End If
	Next
End Sub

Public Shared Function GetCombinations(Of T)(ParamArray enumerables As IEnumerable(Of T)()) As List(Of T())
	Dim combinations = New List(Of T())(enumerables.Length)
	If enumerables.Length > 0 Then
		Dim chain = New T(enumerables.Length - 1) {}
		GetCombinationsRec(sources := enumerables, chain := chain, index := 0, combinations := combinations)
	End If
	Return combinations
End Function

Code in C#.NET:

private static void GetCombinationsRec<T>(IList<IEnumerable<T>> sources, T[] chain, int index, ICollection<T[]> combinations) {
	foreach (var element in sources[index]) {
		chain[index] = element;
		if (index == sources.Count - 1) {
			var finalChain = new T[chain.Length];
			chain.CopyTo(finalChain, 0);
			combinations.Add(finalChain);
		}
		else {
			GetCombinationsRec(sources: sources, chain: chain, index: index + 1, combinations: combinations);
		}
	}
}

public static List<T[]> GetCombinations<T>(params IEnumerable<T>[] enumerables) {
	var combinations = new List<T[]>(enumerables.Length);
	if (enumerables.Length > 0) {
		var chain = new T[enumerables.Length];
		GetCombinationsRec(sources: enumerables, chain: chain, index: 0, combinations: combinations);
	}
	return combinations;
}

Usage is simple:

Dim list1 = New String() {"hello", "bonjour", "hallo", "hola"}
Dim list2 = New String() {"Erwin", "Larry", "Bill", "Steve"}
Dim list3 = New String() {"!", ".."}
Dim result = Utils.GetCombinations(list1, list2, list3)
For Each r In result
    Debug.Print(String.Join(" "c, r))
Next

or in C#:

var list1 = new[] { "Hello", "Bonjour", "Hallo", "Hola" };
var list2 = new[] { "Erwin", "Larry", "Bill", "Steve" };
var list3 = new[] { "!", "..." };
var result = Utils.GetCombinations(list1, list2, list3);
foreach (r in result) {
    Debug.Print(string.Join(" ", r));
}

As with any recursive function, memory usage can be exponential so make sure you know the number of target combinations is reasonable. Speed-wise, parallelizing this function is not worth it as we are just iterating over the elements.

Embracing KISS

Make everything as simple as possible. But not simpler. — Albert Einstein

Spinach, iron & Popeye

I just finished reading this very interesting paper, published in the Internet Journal of Criminology, by Dr Mike Sutton, who shows that even the most zealous urban myth busters may themselves end up committing the very crimes they are fighting against…
Bon appétit! A copy is available here if the original link is down.

Disclaimer: I have not verified Sutton’s sources…

A piece of wisdom from Warren Buffett

In evaluating people, you look for three qualities: integrity, intelligence, and energy. If you don’t have the first, the other two will kill you. — Warren Buffett, 1993

Le TARP, version 33 A.D.

Dans le Livre VI de ses Annales, Tacite nous rapporte cette “anecdote” de l’an 33, du temps de l’Empereur romain Tibère (et l’année de la mort d’un certain Jésus), qui ne manquera pas de nous délecter, tant elle rappelle l’intervention de l’Etat américain fin 2008 via son Troubled Asset Relief Program.

Affaires intérieures 33 ap. J.-C. (6,15-27) – Traduction Jean-Louis Burnouf, 1859 Répression de l’usure (VI,16-17)

16. Cependant une légion d’accusateurs se déchaîna contre ceux qui s’enrichissaient par l’usure, au mépris d’une loi du dictateur César sur la proportion des créances et des possessions en Italie , loi depuis longtemps mise en oubli par l’intérêt particulier, auquel le bien public est toujours sacrifié. L’usure fut de tout temps le fléau de cette ville, et une cause sans cesse renaissante de discordes et de séditions. Aussi, même dans des siècles où les mœurs étaient moins corrompues, on s’occupa de la combattre. Les Douze Tables réduisirent d’abord à un pour cent l’intérêt, qui, auparavant, n’avait de bornes que la cupidité des riches. Ensuite un tribun le fit encore diminuer de moitié ; enfin on défendit tout prêt à usure, et de nombreux plébiscites furent rendus pour prévenir les fraudes de l’avarice, qui, tant de fois réprimées, se reproduisaient avec une merveilleuse adresse. Le préteur Gracchus, devant qui se faisaient les poursuites dont nous parlons ici, fut effrayé du grand nombre des accusés et consulta le sénat. Les sénateurs alarmés (car pas un ne se sentait irréprochable) demandèrent grâce au prince. Leur prière fut entendue, et dix-huit mois furent donnés à chacun pour régler ses affaires domestiques comme la loi l’exigeait.

17. Des remboursements qui remuaient à la fois toutes les dettes, et la perte des biens de tant de condamnés, qui accumulait dans le fisc ou dans l’épargne les espèces monnayées, rendirent l’argent rare. Ajoutez un décret du sénat qui enjoignait aux prêteurs de placer en biens-fonds situés dans l’Italie les deux tiers de leurs créances. Or ceux-ci les exigeaient en entier ; et les débiteurs, requis de payer, ne pouvaient sans honte rester au-dessous de leurs engagements. En vain ils courent, ils sollicitent ; le tribunal du préteur retentit bientôt de demandes. Les ventes et les achats, où l’on avait cru trouver un remède, augmentèrent le mal. Plus d’emprunts possibles ; les riches serraient leur argent pour acheter des terres. La multitude des ventes en fit tomber le prix ; et plus on était obéré, plus on avait de peine à trouver des acheteurs. Beaucoup de fortunes étaient renversées, et la perte des biens entraînait celle du rang et de la réputation. Enfin Tibère soulagea cette détresse en faisant un fonds de cent millions de sesterces, sur lesquels l’État prêtait sans intérêt, pendant trois ans, à condition que le débiteur donnerait une caution en biens-fonds du double de la somme empruntée. Ainsi l’on vit renaître le crédit, et peu à peu les particuliers même prêtèrent. Quant aux achats de biens, on ne s’en tint pas à la rigueur du sénatus-consulte ; et c’est le sort de toutes les réformes, sévères au commencement, à la fin négligées.

100 millions de sesterces, cela représentait 19 483 561 F du temps de Burnouf (confirmé par le Littré). En 1890, la valeur à parité de pouvoir d’achat était selon plusieurs sources concordantes de 3,30 euros pour un franc. Sachant que le franc germinal, bimétallique de l’Union latine (précurseure de l’UEM, établie le 23 décembre 1865 lors de la Convention de Paris comme “Prélude aux fédérations pacifiques du futur”, selon les terme de Félix Esquirou de Parieu) venait de s’affaiblir suite à la découverte d’importants gisements d’argents (en Alaska notamment), on peut raisonnablement estimer que trente ans auparavant, la valeur p.p.a. du franc était de 4 euros pour un franc. Les 100 millions de sesterces représentent donc l’équivalent de 75 millions d’euros actuels (en extrapolant les chiffres donnés par Robert Etienne dans La vie quotidienne à Pompéi (Hachette, 1966), on aboutit à une estimation similaire, à quelques millions d’euros près).

Si l’on suppose que cette crise était surtout circonscrite aux populations d’Italie, lesquelles représentaient probablement 10% d’un Empire de 50 millions d’habitants, cela fait 15€ par habitant, ou 60 sesterces, le salaire mensuel d’un instituteur romain.
De l’autre côté de l’Atlantique, 750 milliards de dollars mis sur la table, ce sont $2500 par habitant, là aussi l’équivalent du salaire mensuel d’un jeune professeur en école élémentaire publique

Moins d’un siècle après la fin de règne de Tibère, l’Empire romain connaîtra son apogée avec Trajan. Les Etats-Unis seraient-ils seulement à l’aube de leur âge d’or ?

Happy birthday, Farmers Group, Inc.

As I was trying to figure out the exact cut-off times for submitting exercise notice on options, be it early or at expiration date, I stumbled on an interesting case of profitable wildcard option exercise on Farmers Group, Inc. some 22 years ago.

On Friday, the 17th of June 1988, holders of OTM put option contracts on this stock (OTM at the closing time of regular trading hours, which by then was 3:00 PM on PHLX), submitted an exercise notice at 6:00 PM, therefore bypassing the exchange cut-off time of 4:30 PM (still in effect today) but not OCC‘s of 7:00 PM (has not changed either since then though technically 6:30 PM is a safe limit, according to an OIC expert I talked to, who also mentionned that nowadays nobody can exercise after 4:30 PM on expiration Friday).
Why? Because at 6:00 PM, this very Friday, the California Insurance Department barred a takeover of Farmers Group, Inc, which caused a substantial decline in the value of the stock and changed the moneyness of formerly worthless put options.

As of 2010, exercising an officially OTM option at expiration is still possible, though the OCC no longer accepts exercise notices after 4:30 PM. If a broker imposes an earlier cut-off time, he would benefit from exercising OTM options abandoned by its customer (who no longer can decide to exercise), should the market conditions make it worthwhile. Yet they would not need to pay this profit back to their customer since the official closing price was OTM… This is not very ethical for the customer (if the latter is not allowed to submit exercise notice after 3:30 PM for example), but it would be a waste of free money not to do it.

I wonder to which extent brokers are aware of this opportunity, whether it is a common practice, and how much they can really make out of it…

Then, when we talk about early exercise of cash-settled index options, like OEX, it is possible to exercise at the closing price (determined at 3:00 PM) until 3:20 PM CST the same day, according to CBOE’s Rule 11.1, .03:

Clearing Members must follow the procedures of the Clearing Corporation when exercising American-style cash-settled index option contracts issued or to be issued in any account at the Clearing Corporation. Members must also follow the procedures set forth below with respect to American-style cash-settled index options: (a) For all contracts exercised by the member or by any customer of the member, an “Exercise Advice” must be delivered by the member in such form or manner prescribed by the Exchange to a place designated by the Exchange no later than 3:20 p.m. (CT), or if trading hours are extended or modified in the applicable option class, no later than five (5) minutes after the close of trading on that day.

According to the OIC, it is normally not possible for an OCC member to bypass the exchange’s cut-off time, though I wonder whether it can be tolerated (like in the case of Farmers Group, Inc.)…

For physically-settled options, the only closing price that matters is the one on expiration Friday. If you exercise early, you immediately become long (or short) of securities; if you want to close your position right away you will have to use the after hours fair trading price, not the artificial and outdated closing price.

On cash-settled options however, an arbitrage strategy could consist in buying a call, selling the underlying to delta-hedge, and wait for a big downward move to occur after close and before 3:20 PM. This would allow you to exercise the call at an artificially high price, buy back the underlying at a low price, and therefore book a free profit. The reverse applies when being long a put and the underlying.
If there is no big move (and there usually isn’t any), you are good to unwind your delta-hedged position, hoping the implied volatility of the option will not have made your lose some money (and it is more likely to go down than to go up, since there has been no sudden move on the underlying), in the case you would not have hedged your vega.

Note: All referenced times are CST.

L’avenir de la zone euro : une erreur du passé, selon Charles Gave

Sorry, this entry is only available in French. For the sake of viewer convenience, the content is shown below in the alternative language. You may click the link to switch the active language.

Cette conférence clairvoyante de lucidité, donnée à l’ENS en décembre 2009, laisse augurer de sombres jours pour l’Union européenne. La seule alternative plausible à l’effective mise sous tutelle du Vieux Continent par l’Allemagne, telle qu’attendue par Charles Gave, serait la sortie pure et simple de la zone euro ; permise par les reliquats de nationalisme présent dans chaque pays et les fausses croyances que la suppression du symptôme guérira le mal sous-jacent (le keynésianisme).

Lorsqu’une force extranationale est perçue comme responsable de la paupérisation d’un peuple qui s’estimait jusqu’alors libre, les plus mauvaises tendances de l’homme on tendance à se réveiller…
Frustration, planche à billet, hyperinflation, élection, et après ?
Il semblerait qu’une période prospère s’achève bientôt, et que nous allons devoir faire face aux turbulences qui accompagnent toujours la mise en place d’un nouvel ordre mondial.


Charles Gave – Euro/Ligne Maginot, même logique by les_ernest

Hayek vs. Keynes – The Rap

Une production econstories.tv.


Hayek contre Keynes – VOSTfr by Liberte_Cherie

How to replace Drupal core’s tracker module using views

This can be pretty handy, especially if you would like to customize it a bit more and add other tabs. Here is a simple step-by-step tutorial:

  1. Disable Drupal’s original core tracker module.
  2. Install views.
  3. Go to Site Building > Views and enable the tracker view.
  4. In the tracker view, go to the Page item, and rename it for example as “Recent posts” in Basic settings > Name and Basic settings > Title.  Make sure you click on override before saving, so that you keep the original configuration in Defaults.
  5. In the Page settings fieldset, set Path to tracker/all and the type to Default menu tab. Set Title to Recent posts and Weight to -10. Click on update and when asked for the Parent menu item, select Normal menu item, and once again type Recent posts as Title. Click on update. We are done with this page type that will display the latest nodes modifications by all users. You can now enjoy the power of views and tweak the display to precisely show what you have in mind.
  6. In the left drop-down list, select Page and click Add display. Rename it for example as “My recent posts” in Basic settings > Name and Basic settings > Title.  Make sure you click on override before saving, so that you keep a version of the original values.
  7. In the Page settings fieldset, set Path to tracker/my and the type to Menu tab. Set Title to My recent posts and Weight to 1. Click on update.
  8. In the Arguments fieldset, click on Node: User posted or commented (if it doesn’t exist, add it), and as the Action to take if argument is not present, select Provide default argumentUser ID from logged in user.
  9. That’s it! The link to your new tracker view is mysite.com/tracker; two tabs will be displayed just like in the original core module. You may for example create a menu item that links to this page.

Cloning objects with events in Visual Basic .NET

The easiest way to clone an object (deep copy) in .NET is to use the serialization functions available:

    Public Shared Function CloneObject(ByVal obj As Object) As Object
        If Not obj Is Nothing Then
            Dim bf = New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
            Dim fs = New System.IO.MemoryStream()
            bf.Serialize(fs, obj)
            fs.Seek(0, System.IO.SeekOrigin.Begin)
            Dim copy = CType(bf.Deserialize(fs), Object)
            fs.Close()
            Return copy
        Else
            Return Nothing
        End If
    End Function

Though the performance is not very good, for occasional operations it will do the job perfectly. However, I was confronted to the following problem: what if there are events inside the class, to which other objects have subscribed? I found several methods (and functions :-)) on various places over the Internet; they basically were:

  • Implement ISerializable yourself (meaning you have to update it each time you modify the class);
  • Disconnect from events (retrieved using Reflection), serialize the object, and then reconnect the events (I could not make this working properly);
  • Implement a serialization surrogate;
  • Implement your events in a separate class that is not serialized;
  • Implement your events in a C# base class.

Plenty of potential solutions, but none of them was good enough for me. So I played around with Reflection and found something that nobody else might have done so far. For a cloning interface that does just a shallow copy, like what MemberwiseClone does, but without event, I wrote this:

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim cl = New MyClassName(Me)
        'Here we don't capture events, only normal fields, including non public ones (private, protected...)
        Dim FldInfos() As Reflection.FieldInfo = Me.GetType.GetFields(Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic)
        For Each FldInfo As Reflection.FieldInfo In FldInfos
            FldInfo.SetValue(cl, FldInfo.GetValue(Me)) 'For serialization purpose we just need not to have events, so no need to perform a deep copy of the fields.
        Next
        Return cl
    End Function

Now if one of your class member is an object with events (or if you want to perform a deep copy), you should call its clone method (to be implemented the same way) when performing the FldInfo.SetValue, like this:

        For Each FldInfo As Reflection.FieldInfo In FldInfos
            If FldInfo.Name <> "MyObjectWithEvents" Then
                FldInfo.SetValue(cl, FldInfo.GetValue(Me)) 'It is not really necessary to clone a possible reference class member here for serialization purpose, we just need not to have events in the clone
            Else
                FldInfo.SetValue(cl, Me.MyObjectWithEvents.Clone())
            End If
        Next

If you have an object that is for example a dictionary of objects with events, you can call this:

        For Each FldInfo As Reflection.FieldInfo In FldInfos
            If FldInfo.Name <> "MyObjectsWithEventsDictionary" Then
                FldInfo.SetValue(cl, MyLib.CloneObject(FldInfo.GetValue(Me))) 
            Else
                FldInfo.SetValue(cl, Me.MyObjectsWithEventsDictionary.ToDictionary(Of String, MyObjectWithEvent)(Function(entry) entry.Key, Function(entry) CType(entry.Value.Clone(), MyObjectWithEvent)))
            End If
        Next

Finally, if you intend to use the Clone interface to serialize objects, you should make sure you don’t include class members marked as NonSerialized():

        For Each FldInfo As Reflection.FieldInfo In FldInfos
            If Not FldInfo.IsNotSerialized Then
                FldInfo.SetValue(cl, FldInfo.GetValue(Me))
            End If
        Next

I hope this will give you an insight to build something more tailored to your needs. There are other optimizations I can already think of, such as implementing a recursive Clone function where you would just put your original object and a virgin instance of it as a reference, and get a perfect serializable deep copy, whatever the class members and sub class members are! This could become a universal Clone method…

How to sort WordPress posts by modified date instead of published date?

Here is the simple solution. Simply use this:

<?php query_posts($query_string . '&orderby=modified&order=desc'); ?>

before where the Loop checks for posts:

<?php /* If there are any posts: */ 
if (have_posts()) ...
?>

It basically adds a condition to the Loop. Enjoy!

Réchauffement climatique : obscurité ou obscurantisme ?

Sorry, this entry is only available in French. For the sake of viewer convenience, the content is shown below in the alternative language. You may click the link to switch the active language.

La complaisance dans un consensus mou n’est pas propice à l’établissement d’une vérité scientifique. Qu’on l’oublie, et c’est bientôt tout l’édifice qui s’écroule.

Le professeur Vincent Courtillot, géologue physicien et membre de l’académie des sciences, s’est incidemment intéressé de plus près au réchauffement climatique. Il vient au secours de la climatologie, en apportant aux théories à la mode une réfutabilité aussi essentielle que scandaleusement qualifiée d’hérésie par les médias, les politiciens, mais surtout ceux-là mêmes qui se prétendent en être les plus illustres experts.

Il est temps que la masse bascule. Les leaders d’opinion suivront. Il n’existe pas d’intérêt matériel pour une théorie ou pour une autre, simplement une égotisation massive des enjeux.
Les marchés boursiers nous y ont habitué : malheur à celui qui défie la tendance avant que tout le monde s’accorde à reconnaître que le roi est nu. Nous ignorons quand la bulle explosera, notre seule certitude est qu’une théorie coupée de ses fondements scientifiques finit toujours par tirer sa révérence. Il n’y aura pas de choc, pas de ruines, pas de victimes. La masse ne s’enrichit pas à cultiver son irréaliste culpabilité ; en devenant sa propre victime, elle appauvrit sa capacité à résoudre ses véritables problèmes.

Dans cette conférence donnée à l’Université de Nantes, Vincent Courtillot tente d’apporter une nouvelle lecture aux données brutes dont nous disposons, et qui ont été malmenées par des experts auto-proclamés pendant de si longues années. Loin du sensationnalisme d’un Al Gore ou de Channel 4, c’est ici un discours que l’on peut saluer tant pour sa rigueur que pour sa clarté. En un mot, une contribution véritablement constructive au débat, sans polémique. Ceux qui auront besoin de plus de détails pourront étancher leur curiosité en consultant les nombreuses références sur la page professionnelle de Vincent Courtillot.

Stay hungry, Stay foolish!

I would like to share with you this very insightful commencement address that Steve Jobs, CEO of Apple Computers and Pixar Animation Studio delivered for the Stanford Graduation Ceremony, on June 12, 2005. Stay inspired.

The original text can be found here and a French translation there.

ASIN to EAN converter

Since I was needing an EAN to ASIN converter and ASIN to EAN converter (UPC/barcode and Amazon code), but could not find any on the web, I decided to write one myself. It is always fun to learn a new API (here I used Amazon Web Services). And when it works exactly as you expect, you are definitely API!

You can input several codes (batch mode) by separating them with “;” (semicolon). The output will be one column with the original code and another with the converted code.

So, long story short, here comes the beauty, and the beast (also available here on a dedicated page/window):

This converter can easily be embedded on your own website using the following code:

<iframe style="border: solid 1px #ccc;" src="https://www3.erwinmayer.com/labs/asin2ean/" width="490" height="630"></iframe>

Latest features:
30/12/2014: Tab in URL and locale persistence.
19/12/2014: Responsive/Mobile-friendly version.
09/12/2014: Much faster batch operations & UI rewritten for easier readability.
09/06/2014: UI improvements for batch operations.
30/04/2014: Added support for BR (Brazil) and IN (India) locales.
02/10/2011: Added support for ES (Spain) locale.
27/08/2011: Added support for IT (Italy) and CN (China) locales.

Please feel free to report any bug you might encounter, or suggest improvements.

I may be available for consulting work on a case by case basis. Just drop me a note if needed.

Next page »